NC231372. Dynamic Graph
描述
输入描述
The first line contains integers --- the numbers of vertices of the graph, the number of operations in the graph, and the modulo.
Then lines follow. The -th line contains the -th operation. The format of the operation input is shown above.
In operations, all tokens are non-negative integers. .It's guaranteed that in each operation , the must be an operation of type and it has not been deleted by another operation .第一行有 个整数, 。接下来有 行,每行描述一个操作。操作格式同题目描述。
题目保证,所有输入的数均为非负整数,且 .
题目保证执行第 种操作时, 对应的操作为第 种,且还未被删。
输出描述
For each operation of types , output a line containing the answer.对于每个询问操作,输出一行一个整数表示答案。
示例1
输入:
10 19 96 1 3 1 48 1 3 2 16 2 2 2 1 1 3 3 24 1 2 2 16 1 2 3 6 1 2 3 48 1 2 2 48 1 1 3 16 1 3 3 48 2 5 3 3 4 16 3 3 3 8 1 2 1 48 2 6 3 3 1 32 2 7 2 8
输出:
0 1 1
C++ 解法, 执行用时: 179ms, 内存消耗: 25976K, 提交时间: 2021-12-28 20:01:02
#include<cstdio> #include<algorithm> #include<vector> using namespace std; const int MAXN=1e5+5,MAXS=2e7; int gcd(int a,int b){ if(!b) return a; return gcd(b,a%b); } int n,m,F,op[MAXN][4],edt[MAXN],ans[MAXN]; struct Edge{ int u,v,w; }; vector<Edge> ed[MAXN<<2]; #define lc k<<1 #define rc k<<1|1 #define ls lc,l,mid #define rs rc,mid+1,r void Modify(int k,int l,int r,int x,int y){ if(x<=l&&r<=y){ ed[k].push_back((Edge){op[x][1],op[x][2],op[x][3]}); return ; } int mid=l+r>>1; if(x<=mid) Modify(ls,x,y); if(mid<y) Modify(rs,x,y); return ; } struct Change{ int *w,v; }stk[MAXS]; int top; inline void c(int &x,int y){ if(x!=y){ stk[++top]=(Change){&x,x}; x=y; } } int pre[MAXN],gs[MAXN],siz[MAXN],fw[MAXN],sum[MAXN]; int fnd(int x){ if(x==pre[x]) return sum[x]=0,x; int res=fnd(pre[x]); sum[x]=sum[pre[x]]^fw[x]; return res; } void Query(int k,int l,int r){ int tp=top; for(Edge e:ed[k]){ int u=e.u,v=e.v; int x=fnd(u),y=fnd(v); if(x==y){ int g=gcd(gs[x],e.w*2); if(__builtin_ctz(sum[u]^sum[v]^e.w)<__builtin_ctz(g)) g>>=1; c(gs[x],g); }else{ //printf("Merge %d %d\n",x,y); if(siz[x]>siz[y]) swap(x,y); fw[x]=sum[u]^sum[v]^e.w; c(pre[x],y); c(siz[y],siz[x]+siz[y]); c(gs[y],gcd(gcd(gs[x],gs[y]),e.w*2)); } } if(l==r){ if(op[l][0]==3){ //puts("op3"); int u=op[l][1],v=op[l][2],w=op[l][3]; int x=fnd(u),y=fnd(v); //printf("x %d y %d\n",x,y); if(x==y){ int g=gs[x]; if(__builtin_ctz(sum[u]^sum[v])<__builtin_ctz(g)) ans[l]=(w%g==g/2); else ans[l]=(w%g==0); } } }else{ int mid=l+r>>1; Query(ls); Query(rs); } while(top>tp){ *stk[top].w=stk[top].v; top--; } return ; } int main(){ //freopen("rand","r",stdin); scanf("%d%d%d",&n,&m,&F); for(int i=1; i<=m; i++){ scanf("%d%d",op[i],op[i]+1); if(op[i][0]!=2) scanf("%d%d",op[i]+2,op[i]+3); else edt[op[i][1]]=i; } for(int i=1; i<=m; i++) if(op[i][0]==1) Modify(1,1,m,i,edt[i]?edt[i]:m); for(int i=1; i<=n; i++) pre[i]=i,siz[i]=1,gs[i]=F; Query(1,1,m); for(int i=1; i<=m; i++) if(op[i][0]==3) printf("%d\n",ans[i]); return 0; }