This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define X first
#define Y second
#define y0 y12
#define y1 y22
#define INF 1987654321
#define PI 3.141592653589793238462643383279502884
#define fup(i,a,b,c) for(int (i)=(a);(i)<=(b);(i)+=(c))
#define fdn(i,a,b,c) for(int (i)=(a);(i)>=(b);(i)-=(c))
#define MEM0(a) memset((a),0,sizeof(a))
#define MEM_1(a) memset((a),-1,sizeof(a))
#define ALL(a) a.begin(),a.end()
#define COMPRESS(a) sort(ALL(a));a.resize(unique(ALL(a))-a.begin())
#define SYNC ios_base::sync_with_stdio(false);cin.tie(0)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int, int> Pi;
typedef pair<ll, ll> Pll;
typedef pair<db, db> Pd;
typedef vector<int> Vi;
typedef vector<ll> Vll;
typedef vector<double> Vd;
typedef vector<Pi> VPi;
typedef vector<Pll> VPll;
typedef vector<Pd> VPd;
typedef tuple<int, int, int> iii;
typedef tuple<int,int,int,int> iiii;
typedef tuple<ll, ll, ll> LLL;
typedef vector<iii> Viii;
typedef vector<LLL> VLLL;
typedef complex<double> base;
const int MOD = 1000000007;
ll POW(ll a, ll b, ll MMM=MOD) {ll ret=1; for(;b;b>>=1,a=(a*a)%MMM)if(b&1)ret=(ret*a)% MMM; return ret; }
int dx[] = { 0,1,0,-1,1,1,-1,-1 }, dy[] = { 1,0,-1,0,1,-1,1,-1 };
int ddx[]={2,2,-2,-2,1,1,-1,-1},ddy[]={1,-1,1,-1,2,-2,2,-2};
Vi v[100001];
int p[100001];
int find(int x){
if(p[x]==x)return x;
return p[x]=find(p[x]);
}
void merge(int x,int y){
x=find(x),y=find(y);
if(x!=y)p[x]=y;
}
int tree[262144],lazy[262144],hld[100001],cnt[100001],num[100001],idx[100001],parent[100001],depth[100001],cc;
void init(int node,int S, int E){
if(S==E){
tree[node]=1;
return;
}
init(node*2,S,(S+E)/2);
init(node*2+1,(S+E)/2+1,E);
tree[node]=tree[node*2]+tree[node*2+1];
}
void propagation(int node,int S,int E){
if(lazy[node]){
tree[node]=0;
if(S!=E){
lazy[node*2]=1;
lazy[node*2+1]=1;
}
lazy[node]=0;
}
}
void upd(int node, int S, int E, int i, int j)
{
propagation(node, S, E);
if (i > E || j < S) return;
if (j >= E && i <= S)
{
lazy[node] = 1;
propagation(node, S, E);
return;
}
upd(2 * node, S, (S + E) / 2, i, j);
upd(2 * node + 1, (S + E) / 2 + 1, E, i, j);
tree[node] = tree[2 * node] + tree[2 * node + 1];
}
int find(int node, int S, int E, int i, int j)
{
propagation(node, S, E);
if (i > E || j < S)return 0;
if (i <= S && j >= E)return tree[node];
return find(node * 2, S, (S + E) / 2, i, j)+ find(node * 2 + 1, (S + E) / 2 + 1, E, i, j);
}
void dfs(int N,int p,int d)
{
parent[N]=p;
depth[N]=d;
cnt[N]=1;
for(int next:v[N])
{
if(next==p)continue;
dfs(next,N,d+1);
cnt[N]+=cnt[next];
}
}
void HLD(int N,int p)
{
int c=-1;
num[N]=++cc;
idx[num[N]]=N;
for(int next:v[N])
{
if(next==p)continue;
if(c==-1 || cnt[next]>cnt[c])c=next;
}
if(c!=-1)
{
hld[c]=hld[N];
HLD(c,N);
}
for(int next:v[N])
{
if(next==p || next==c)continue;
hld[next]=next;
HLD(next,N);
}
}
int n,q;
void upd(int x,int y){
while(hld[x]!=hld[y])
{
if(depth[hld[x]]>depth[hld[y]])
{
upd(1,1,n,num[hld[x]],num[x]);
x=parent[hld[x]];
}
else
{
upd(1,1,n,num[hld[y]],num[y]);
y=parent[hld[y]];
}
}
if(depth[x]>depth[y])swap(x,y);
upd(1,1,n,num[x]+1,num[y]);
}
int query(int x,int y)
{
int res=0;
while(hld[x]!=hld[y])
{
if(depth[hld[x]]>depth[hld[y]])
{
res+=find(1,1,n,num[hld[x]],num[x]);
x=parent[hld[x]];
}
else
{
res+=find(1,1,n,num[hld[y]],num[y]);
y=parent[hld[y]];
}
}
if(depth[x]>depth[y])swap(x,y);
res+=find(1,1,n,num[x]+1,num[y]);
return res;
}
iii Q[300000];
int main() {
scanf("%d%d",&n,&q);
iota(p,p+n+1,0);
fup(i,0,q-1,1){
int t,x,y;
scanf("%d%d%d",&t,&x,&y);
Q[i]=iii(t,x,y);
if(t==1){
if(find(x)!=find(y)){
v[x].pb(y);
v[y].pb(x);
}
merge(x,y);
}
}
fup(i,1,n,1){
if(!num[i]){
dfs(i,-1,0);
hld[i]=i;
HLD(i,-1);
}
}
init(1,1,n);
iota(p,p+n+1,0);
fup(i,0,q-1,1){
auto [t,x,y]=Q[i];
if(t==1){
if(find(x)==find(y)){
upd(x,y);
}
merge(x,y);
}else{
if(find(x)!=find(y)){
puts("-1");
continue;
}
printf("%d\n",query(x,y));
}
}
}
Compilation message (stderr)
road_development.cpp: In function 'int main()':
road_development.cpp:10:30: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
10 | #define fup(i,a,b,c) for(int (i)=(a);(i)<=(b);(i)+=(c))
| ^
road_development.cpp:171:2: note: in expansion of macro 'fup'
171 | fup(i,0,q-1,1){
| ^~~
road_development.cpp:10:30: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
10 | #define fup(i,a,b,c) for(int (i)=(a);(i)<=(b);(i)+=(c))
| ^
road_development.cpp:183:2: note: in expansion of macro 'fup'
183 | fup(i,1,n,1){
| ^~~
road_development.cpp:10:30: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
10 | #define fup(i,a,b,c) for(int (i)=(a);(i)<=(b);(i)+=(c))
| ^
road_development.cpp:192:2: note: in expansion of macro 'fup'
192 | fup(i,0,q-1,1){
| ^~~
road_development.cpp:169:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
169 | scanf("%d%d",&n,&q);
| ~~~~~^~~~~~~~~~~~~~
road_development.cpp:173:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
173 | scanf("%d%d%d",&t,&x,&y);
| ~~~~~^~~~~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |