Description
N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数。
Input
第一行四个整数N、M、K、type,代表点数、边数、询问数以及询问是否加密。
接下来M行,代表图中的每条边。
接下来K行,每行两个整数L、R代表一组询问。对于type=0的测试点,读入的L和R即为询问的L、R;对于type=1的测试点,每组询问的L、R应为L xor lastans和R xor lastans。
Output
K行每行一个整数代表该组询问的联通块个数。
Sample Input
3 5 4 0
1 3
1 2
2 1
3 2
2 2
2 3
1 5
5 5
1 2
1 3
1 2
2 1
3 2
2 2
2 3
1 5
5 5
1 2
Sample Output
2
1
3
1
1
3
1
解题思路:
LCT维护连通图,维护最早被删除的边。
像HH的项链那样搞就好了。
只不过是主席树。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 const int N=1000000; 5 class PST{ 6 #define lll tr[spc].ls 7 #define rrr tr[spc].rs 8 public: 9 void update(int l,int r,int &spc,int lst,int pos,int v) 10 { 11 spc=++siz; 12 tr[spc]=tr[lst]; 13 tr[spc].val+=v; 14 if(l==r) 15 return ; 16 int mid=(l+r)>>1; 17 if(pos<=mid) 18 update(l,mid,tr[spc].ls,tr[lst].ls,pos,v); 19 else 20 update(mid+1,r,tr[spc].rs,tr[lst].rs,pos,v); 21 return ; 22 } 23 int query(int l,int r,int ll,int rr,int spc) 24 { 25 if(!spc) 26 return 0; 27 if(l>rr||ll>r) 28 return 0; 29 if(ll<=l&&r<=rr) 30 return tr[spc].val; 31 int mid=(l+r)>>1; 32 return query(l,mid,ll,rr,lll)+query(mid+1,r,ll,rr,rrr); 33 } 34 void fit(int array_size) 35 { 36 size=array_size; 37 return ; 38 } 39 int Query(int l,int r) 40 { 41 int ans=0; 42 ans=query(1,size,l,r,root[r]); 43 return ans; 44 } 45 void ops(int pos) 46 { 47 root[pos]=root[pos-1]; 48 return ; 49 } 50 void Add(int i,int pos,int v) 51 { 52 update(1,size,root[i],root[i],pos,v); 53 return ; 54 } 55 private: 56 struct trnt{ 57 int ls; 58 int rs; 59 int val; 60 }tr[N*10]; 61 int root[N]; 62 int siz; 63 int size; 64 #undef lll 65 #undef rrr 66 }P; 67 class LCT{ 68 #define lll tr[spc].ch[0] 69 #define rrr tr[spc].ch[1] 70 #define ls ch[0] 71 #define rs ch[1] 72 public: 73 bool whc(int spc) 74 { 75 return tr[tr[spc].fa].rs==spc; 76 } 77 void pushup(int spc) 78 { 79 tr[spc].mv=tr[spc].sl; 80 if(lll) 81 tr[spc].mv=std::min(tr[spc].mv,tr[lll].mv); 82 if(rrr) 83 tr[spc].mv=std::min(tr[spc].mv,tr[rrr].mv); 84 return ; 85 } 86 void trr(int spc) 87 { 88 if(!spc) 89 return ; 90 std::swap(lll,rrr); 91 tr[spc].lzt^=1; 92 return ; 93 } 94 void pushdown(int spc) 95 { 96 if(tr[spc].lzt) 97 { 98 trr(lll); 99 trr(rrr); 100 tr[spc].lzt=0; 101 } 102 return ; 103 } 104 void recal(int spc) 105 { 106 if(!tr[spc].anc) 107 recal(tr[spc].fa); 108 pushdown(spc); 109 return ; 110 } 111 void rotate(int spc) 112 { 113 int f=tr[spc].fa; 114 bool k=whc(spc); 115 tr[f].ch[k]=tr[spc].ch[!k]; 116 tr[spc].ch[!k]=f; 117 if(tr[f].anc) 118 { 119 tr[f].anc=0; 120 tr[spc].anc=1; 121 }else 122 tr[tr[f].fa].ch[whc(f)]=spc; 123 tr[spc].fa=tr[f].fa; 124 tr[f].fa=spc; 125 tr[tr[f].ch[k]].fa=f; 126 pushup(f); 127 pushup(spc); 128 return ; 129 } 130 void splay(int spc) 131 { 132 recal(spc); 133 while(!tr[spc].anc) 134 { 135 int f=tr[spc].fa; 136 if(tr[f].anc) 137 { 138 rotate(spc); 139 return ; 140 } 141 if(whc(spc)^whc(f)) 142 rotate(spc); 143 else 144 rotate(f); 145 rotate(spc); 146 } 147 return ; 148 } 149 void access(int spc) 150 { 151 int lst=0; 152 while(spc) 153 { 154 splay(spc); 155 tr[rrr].anc=1; 156 tr[lst].anc=0; 157 rrr=lst; 158 pushup(spc); 159 lst=spc; 160 spc=tr[spc].fa; 161 } 162 return ; 163 } 164 void Mtr(int spc) 165 { 166 access(spc); 167 splay(spc); 168 trr(spc); 169 return ; 170 } 171 void split(int x,int y) 172 { 173 Mtr(x); 174 access(y); 175 splay(y); 176 return ; 177 } 178 void link(int x,int y) 179 { 180 Mtr(x); 181 tr[x].fa=y; 182 return ; 183 } 184 bool check(int x,int y) 185 { 186 Mtr(x); 187 access(y); 188 splay(y); 189 pushdown(y); 190 while(tr[y].ls) 191 { 192 y=tr[y].ls; 193 pushdown(y); 194 } 195 return x==y; 196 } 197 int minplace(int x,int y) 198 { 199 split(x,y); 200 return tr[y].mv; 201 } 202 void cut(int x,int y) 203 { 204 split(x,y); 205 tr[y].ls=0; 206 tr[x].fa=0; 207 tr[x].anc=true; 208 pushup(y); 209 return ; 210 } 211 void fit(int size1,int size2) 212 { 213 siz=size1+size2; 214 for(int i=1;i<=size1;i++) 215 tr[i].sl=0x3f3f3f3f; 216 for(int i=1;i<=size2;i++) 217 tr[i+size1].sl=i; 218 for(int i=1;i<=siz;i++) 219 { 220 tr[i].anc=true; 221 pushup(i); 222 } 223 return ; 224 } 225 private: 226 struct int_2{ 227 int v; 228 int p; 229 }; 230 struct trnt{ 231 int ch[2]; 232 int fa; 233 int lzt; 234 bool anc; 235 int sl; 236 int mv; 237 }tr[N]; 238 int siz; 239 #undef lll 240 #undef rrr 241 #undef ls 242 #undef rs 243 }T; 244 int n,m,k,t; 245 int lastans; 246 int from[N]; 247 int plc[N]; 248 int to[N]; 249 int no[N]; 250 int main() 251 { 252 scanf("%d%d%d%d",&n,&m,&k,&t); 253 for(int i=1;i<=m;i++) 254 { 255 scanf("%d%d",&from[i],&to[i]); 256 no[i]=i; 257 plc[i]=n+i; 258 } 259 T.fit(n,m); 260 P.fit(m); 261 for(int i=1;i<=m;i++) 262 { 263 P.ops(i); 264 int a=from[i],b=to[i]; 265 if(a==b) 266 continue; 267 if(T.check(a,b)) 268 { 269 int pos=T.minplace(a,b); 270 P.Add(i,pos,-1); 271 T.cut(plc[pos],from[pos]); 272 T.cut(plc[pos],to[pos]); 273 } 274 T.link(plc[i],a); 275 T.link(plc[i],b); 276 P.Add(i,i,1); 277 } 278 while(k--) 279 { 280 int l,r; 281 scanf("%d%d",&l,&r); 282 if(t) 283 { 284 l^=lastans; 285 r^=lastans; 286 } 287 lastans=n-P.Query(l,r); 288 printf("%d\n",lastans); 289 } 290 return 0; 291 }