I am the portal of Meng Meng
This question is a support for the addition edge and the deletion of the graph connectivity maintenance, but in view of the particularity of the graph, you can Direct Line tree (heard that the mark is this ...).
However, I am more lazy, do not want to think about how line tree, and then wrote a split treatment and check set, 1A I really touched ...
I didn't think about how to write an undo-by-rank merger, so I wrote a random merge (anyway, the expected complexity is LOGN), and the code starts with a handwritten random number generator ... (I would say that after the module takes 998244353, even if an int overflow can guarantee that the circulation section is more than 10 million ...)
The first Division and the collection, but also learned a new skill haha ...
Say this code on the Bzoj card, really sad ...
1#include <cstdio>2#include <cstring>3#include <algorithm>4#include <vector>5#include <map>6 using namespacestd;7 Const intmaxn=100010;8InlineintRandint () {9 Static intA=151, b=24863, c=9788417, x=1089488183, p=998244353;Tenx=a*x*x+b*x+c;x%=p; One returnx<0? (x=-x): x; A } - structa{intU,V,TP;} A[MAXN]; - voidAddedge (int,int,int); the voidAddQuery (int,int,int); - voidSolveint,int,int); - intFindrootint); - voidMergeset (int,int,vector<int>&); + intid[3][maxn],cnt=0,prt[maxn<<1],qu[maxn<<2],qv[maxn<<2]; - intn,m=1, x1,y1,x2,y2,x,y,s,t; +vector<int>u[maxn<<2],v[maxn<<2],stk[maxn<<2]; Amap<pair<int,int,int>MP; at Charc[ the]; - intMain () { -Freopen ("bzoj_1018.in","R", stdin); -Freopen ("Bzoj_1018.out","W", stdout); -scanf"%d",&n); - for(intI=1; i<=n;i++){ inid[1][i]=++CNT; -id[2][i]=++CNT; to } + for(intI=1; i<=cnt;i++) prt[i]=i; - for(int&I=M;SCANF ("%s", c) = =1&&STRCMP (c,"Exit"); i++){ thescanf"%d%d%d%d",&x1,&y1,&x2,&y2); *x=id[x1][y1];y=Id[x2][y2]; $ if(x>y) Swap (x, y);Panax Notoginsenga[i].u=x;a[i].v=y; - if(!STRCMP (C,"Open")) a[i].tp=1; the Else if(!STRCMP (C,"Close")) a[i].tp=2; + Elsea[i].tp=3; A } the for(intI=1; i<=m;i++){ +x=a[i].u;y=a[i].v; - if(a[i].tp==1){ $ if(!mp.count (Make_pair (x, y))) Mp[make_pair (x, y)]=i; $ } - Else if(a[i].tp==2){ - if(Mp.count (Make_pair (x, y))) { thes=Mp[make_pair (x, y)]; -t=i;WuyiAddedge (1M1); the mp.erase (Make_pair (x, y)); - } Wu } - Else{ Aboutt=i; $AddQuery (1M1); - } - } - for(map<pair<int,int,int>::iterator It=mp.begin (); It!=mp.end (); it++){ AX=it->First.first; +Y=it->First.second; theS=it->second; -t=m; $Addedge (1M1); the } theSolve1M1); the return 0; the } - voidAddedge (intLintRintRT) { in if(s<=l&&t>=R) { the u[rt].push_back (x); the v[rt].push_back (y); About return; the } the intMid= (l+r) >>1; the if(S<=mid) Addedge (l,mid,rt<<1); + if(T>mid) Addedge (mid+1,r,rt<<1|1); - } the voidAddQuery (intLintRintRT) {Bayi if(l==R) { thequ[rt]=x; theqv[rt]=y; - return; - } thequ[rt]|=x; the intMid= (l+r) >>1; the if(T<=mid) AddQuery (l,mid,rt<<1); the ElseAddQuery (mid+1,r,rt<<1|1); - } the voidSolveintLintRintRT) { the if(!qu[rt])return; the for(intI=0;i< (int) u[rt].size (); i++) Mergeset (U[rt][i],v[rt][i],stk[rt]);94 if(l==r) printf (Findroot (Qu[rt]) ==findroot (Qv[rt])?"y\n":"n\n"); the Else{ the intMid= (l+r) >>1; theSolve (l,mid,rt<<1);98Solve (mid+1,r,rt<<1|1); About } - if(!stk[rt].empty ()) for(intI= (int) Stk[rt].size ()-1; i>=0; i--) prt[stk[rt][i]]=Stk[rt][i];101 }102 intFindrootintx) {103 while(prt[x]!=x) x=Prt[x];104 returnx; the }106 voidMergeset (intXinty,vector<int>&a) {107X=findroot (x); y=findroot (y);108 if(x==y)return;109 if(Randint () &1) Swap (x, y); theprt[x]=y;111 a.push_back (x); the}
View Code
Do not know what to add the classification, anyway, is the time to build line tree, add to the CDQ division ...
[SHOI2008] clogged traffic traffic