好题+数据结构神题+感人肺腑pascal被卡系列,我下面的代码几乎写到最优
可怎耐bzoj上pascal开的是O1,c++开的是O2,这怎么可能跑得过!!!
还是说说方法吧,这是一道算贡献的好题,因为我们不可能把边加进去依次算连通块个数
我们考虑在区间[l,r]中每条边i是否能使两个连通块变成1个,什么样的边可以呢?
显然,这条边端点所在的连通块在i加入之前不连通或者是使这两个连通块相连的边号<l
这样算法就呼之欲出了,我们首先依次把边i加入,如果构成环,则弹出环上编号最小的边并记录,否则记为0
这里我们可以用link cut tree解决
下面每次询问,我们只要求[l,r]有多少个数小于l即可
这题有是否强制在线两种情况,在线可以直接rush,但是我第一次TLE之后又写了一遍离线,发现比原来快但还是远远慢于只在线的c++,实在没办法只好弃疗,说一下两种情况
在线:显然这是主席树的经典问题
离线:注意这个个数是满足区间减法的,于是我们可以拆成两个求前缀询问并排序(注意这里用计数排序才有显著的提升),然后按边编号的顺序依次加入然后用树状数组统计,具体见程序
1 const inf=100000007; 2 type node=record 3 l,r,s:longint; 4 end; 5 way=record 6 s,e:longint; 7 end; 8 point=record 9 be,op,y:longint; 10 end; 11 xxx=record 12 po,next:longint; 13 end; 14 15 var son:array[0..400010,1..2] of longint; 16 q,w,v,fa:array[0..400010] of longint; 17 qq:array[0..410010] of point; 18 ee:array[0..400010] of xxx; 19 rev:array[0..400010] of boolean; 20 tree:array[0..200010*22] of node; 21 e:array[0..200010] of way; 22 p,f,a,h,anss:array[0..200010] of longint; 23 len,j,k1,k2,n,m,k,ty,t,i,ans,l,r,mm:longint; 24 25 function min(a,b:longint):longint; 26 begin 27 if w[a]>w[b] then exit(b) else exit(a); 28 end; 29 30 function getf(x:longint):longint; 31 begin 32 if f[x]<>x then f[x]:=getf(f[x]); 33 exit(f[x]); 34 end; 35 36 procedure swap(var a,b:longint); 37 var c:longint; 38 begin 39 c:=a; 40 a:=b; 41 b:=c; 42 end; 43 44 function root(x:longint):boolean; 45 begin 46 exit((son[fa[x],1]<>x) and (son[fa[x],2]<>x)); 47 end; 48 49 procedure update(x:longint); 50 begin 51 v[x]:=min(x,min(v[son[x,1]],v[son[x,2]])); 52 end; 53 54 procedure push(x:longint); 55 begin 56 if rev[x] then 57 begin 58 swap(son[x,1],son[x,2]); 59 rev[son[x,1]]:=not rev[son[x,1]]; 60 rev[son[x,2]]:=not rev[son[x,2]]; 61 rev[x]:=false; 62 end; 63 end; 64 65 procedure rotate(x,w:longint); 66 var y:longint; 67 begin 68 y:=fa[x]; 69 if not root(y) then 70 begin 71 if son[fa[y],1]=y then son[fa[y],1]:=x 72 else son[fa[y],2]:=x; 73 end; 74 fa[x]:=fa[y]; 75 son[y,3-w]:=son[x,w]; 76 if son[x,w]<>0 then fa[son[x,w]]:=y; 77 son[x,w]:=y; 78 fa[y]:=x; 79 update(y); 80 end; 81 82 procedure splay(x:longint); 83 var i,s,y:longint; 84 fl:boolean; 85 begin 86 i:=x; 87 s:=0; 88 while not root(i) do 89 begin 90 inc(s); 91 q[s]:=i; 92 i:=fa[i]; 93 end; 94 inc(s); 95 q[s]:=i; 96 for i:=s downto 1 do 97 push(q[i]); 98 if s=1 then exit; 99 fl:=true; 100 while fl do 101 begin 102 y:=fa[x]; 103 if y=q[s] then 104 begin 105 if son[y,1]=x then rotate(x,2) 106 else rotate(x,1); 107 fl:=false; 108 end 109 else begin 110 if fa[y]=q[s] then fl:=false; 111 if son[fa[y],1]=y then 112 begin 113 if son[y,1]=x then rotate(y,2) 114 else rotate(x,1); 115 rotate(x,2); 116 end 117 else begin 118 if son[y,1]=x then rotate(x,2) 119 else rotate(y,1); 120 rotate(x,1); 121 end; 122 end; 123 end; 124 update(x); 125 end; 126 127 procedure access(x:longint); 128 var y:longint; 129 begin 130 y:=0; 131 repeat 132 splay(x); 133 son[x,2]:=y; 134 update(x); 135 y:=x; 136 x:=fa[x]; 137 until x=0; 138 end; 139 140 procedure makeroot(x:longint); 141 begin 142 access(x); 143 splay(x); 144 rev[x]:=not rev[x]; 145 end; 146 147 procedure link(x,y:longint); 148 begin 149 makeroot(x); 150 fa[x]:=y; 151 end; 152 153 procedure path(x,y:longint); 154 begin 155 makeroot(x); 156 access(y); 157 splay(y); 158 end; 159 160 procedure cut(x,y:longint); 161 begin 162 path(x,y); 163 son[y,1]:=0; 164 fa[x]:=0; 165 end; 166 167 function build(l,r:longint):longint; 168 var m,q:longint; 169 begin 170 inc(t); 171 if l=r then exit(t) 172 else begin 173 m:=(l+r) shr 1; 174 q:=t; 175 tree[q].l:=build(l,m); 176 tree[q].r:=build(m+1,r); 177 exit(q); 178 end; 179 end; 180 181 function add(l,r,last,x:longint):longint; 182 var m,q:longint; 183 begin 184 inc(t); 185 if l=r then 186 begin 187 tree[t].s:=tree[last].s+1; 188 exit(t); 189 end 190 else begin 191 m:=(l+r) shr 1; 192 q:=t; 193 if x<=m then 194 begin 195 tree[q].r:=tree[last].r; 196 tree[q].l:=add(l,m,tree[last].l,x); 197 end 198 else begin 199 tree[q].l:=tree[last].l; 200 tree[q].r:=add(m+1,r,tree[last].r,x); 201 end; 202 tree[q].s:=tree[tree[q].l].s+tree[tree[q].r].s; 203 exit(q); 204 end; 205 end; 206 207 function ask(l,r,x,y:longint):longint; 208 var m,s:longint; 209 begin 210 if l=r then exit(tree[y].s-tree[x].s) 211 else begin 212 m:=(l+r) shr 1; 213 if k1<=m then exit(ask(l,m,tree[x].l,tree[y].l)) 214 else begin 215 s:=tree[tree[y].l].s-tree[tree[x].l].s; 216 exit(s+ask(m+1,r,tree[x].r,tree[y].r)); 217 end; 218 end; 219 end; 220 221 procedure cha(var a,b:point); 222 var c:point; 223 begin 224 c:=a; 225 a:=b; 226 b:=c; 227 end; 228 229 function lowbit(x:longint):longint; 230 begin 231 exit(x and (-x)); 232 end; 233 234 procedure jia(x,y:longint); 235 begin 236 inc(len); 237 ee[len].po:=y; 238 ee[len].next:=p[x]; 239 p[x]:=len; 240 end; 241 242 procedure ins(x:longint); 243 begin 244 while x<=m+1 do 245 begin 246 inc(h[x]); 247 x:=x+lowbit(x); 248 end; 249 end; 250 251 function an(x:longint):longint; 252 begin 253 an:=0; 254 while x>0 do 255 begin 256 an:=an+h[x]; 257 x:=x-lowbit(x); 258 end; 259 end; 260 261 begin 262 readln(n,m,k,ty); 263 for i:=1 to n do 264 begin 265 f[i]:=i; 266 w[i]:=inf; 267 end; 268 t:=n; 269 w[0]:=inf; 270 for i:=1 to m do 271 begin 272 readln(e[i].s,e[i].e); 273 if e[i].s=e[i].e then 274 begin 275 a[i]:=i; 276 continue; 277 end; 278 k1:=getf(e[i].s); 279 k2:=getf(e[i].e); 280 if k1=k2 then //并查集判连通 281 begin 282 path(e[i].s,e[i].e); 283 l:=v[e[i].e]; 284 a[i]:=w[l]; 285 cut(e[w[l]].s,l); 286 cut(e[w[l]].e,l); 287 end 288 else f[k1]:=k2; 289 inc(t); w[t]:=i; 290 link(e[i].s,t); 291 link(e[i].e,t); 292 end; 293 if ty=1 then //在线做法 294 begin 295 t:=0; 296 h[0]:=build(0,m); 297 for i:=1 to m do 298 begin 299 h[i]:=add(0,m,h[i-1],a[i]); 300 end; 301 ans:=0; 302 for i:=1 to k do 303 begin 304 readln(l,r); 305 l:=l xor ans; 306 r:=r xor ans; 307 if l>r then swap(l,r); 308 k1:=l-1; 309 ans:=n-ask(0,m,h[l-1],h[r]); 310 writeln(ans); 311 end; 312 end 313 else begin //离线做法 314 t:=0; 315 for i:=1 to k do 316 begin 317 readln(l,r); 318 inc(t); 319 qq[t].op:=-1; 320 qq[t].y:=l; 321 qq[t].be:=i; 322 jia(r,t); 323 inc(t); 324 qq[t].op:=1; 325 jia(l-1,t); 326 qq[t].y:=l; 327 qq[t].be:=i; 328 end; 329 j:=1; 330 a[m+1]:=inf; 331 for i:=0 to m do 332 begin 333 while j<=i do 334 begin 335 ins(a[j]+1); //树状数组编号从1开始,所以+1 336 inc(j); 337 end; 338 l:=p[i]; 339 while l<>0 do 340 begin 341 r:=ee[l].po; 342 inc(anss[qq[r].be],qq[r].op*an(qq[r].y)); 343 l:=ee[l].next; 344 end; 345 end; 346 for i:=1 to k do 347 writeln(anss[i]+n); 348 end; 349 end.