【BZOJ3514】Codechef MARCH14 GERALD07加强版(LCT)
题意:N个点M条边的无向图,q次询问保留图中编号在[l,r]的边的时候图中的联通块个数。
询问加密,强制在线
n,m,q<=200000
题意:RYZ作业
以下转载自hzwer http://hzwer.com/4358.html 本人实力有限难以清晰描述
有一个比较猎奇的做法:首先把边依次加到图中,若当前这条边与图中的边形成了环,那么把这个环中最早加进来的边弹出去
并将每条边把哪条边弹了出去记录下来:ntr[i] = j,特别地,要是没有弹出边,ntr[i] = 0;
这个显然是可以用LCT来弄的对吧。
然后对于每个询问,我们的答案就是对l~r中ntr小于l的边求和,并用n减去这个值
正确性可以YY一下:
如果一条边的ntr >= l,那么显然他可以与从l ~ r中的边形成环,那么它对答案没有贡献
反之如果一条边的ntr < l那么它与从l ~ r中的边是不能形成环的,那么他对答案的贡献为-1
对于查询从l ~ r中有多少边的ntr小于l,我反正是用的函数式线段树
话说LCT自带十倍常数 被卡了一天半 最后还是把swap和isroot拆出来才卡过的……
1 var t,c:array[0..4100000,0..2]of longint; 2 mx,a,b,rev,fa,root,q:array[0..4100000]of longint; 3 x,y:array[1..2100000]of longint; 4 n,m,cnt,i,k,tp,tmp,lastans,l,r,top,tt:longint; 5 6 {function isroot(x:longint):boolean; 7 begin 8 if (t[fa[x],0]<>x)and(t[fa[x],1]<>x) then exit(true); 9 exit(false); 10 end; 11 } 12 {procedure swap(var x,y:longint); 13 var t:longint; 14 begin 15 t:=x; x:=y; y:=t; 16 end; } 17 18 procedure pushup(x:longint); 19 var l,r:longint; 20 begin 21 l:=t[x,0]; r:=t[x,1]; 22 mx[x]:=x; 23 if b[mx[l]]<b[mx[x]] then mx[x]:=mx[l]; 24 if b[mx[r]]<b[mx[x]] then mx[x]:=mx[r]; 25 end; 26 27 procedure pushdown(x:longint); 28 var l,r:longint; 29 begin 30 l:=t[x,0]; r:=t[x,1]; 31 if rev[x]>0 then 32 begin 33 rev[x]:=rev[x] xor 1; rev[l]:=rev[l] xor 1; rev[r]:=rev[r] xor 1; 34 // swap(t[x,0],t[x,1]); 35 tt:=t[x,0]; t[x,0]:=t[x,1]; t[x,1]:=tt; 36 end; 37 end; 38 39 procedure rotate(x:longint); 40 var y,z,l,r:longint; 41 begin 42 y:=fa[x]; z:=fa[y]; 43 if t[y,0]=x then l:=0 44 else l:=1; 45 r:=l xor 1; 46 // if not isroot(y) then 47 if (t[fa[y],0]=y)or(t[fa[y],1]=y) then 48 begin 49 if t[z,0]=y then t[z,0]:=x 50 else t[z,1]:=x; 51 end; 52 fa[y]:=x; fa[x]:=z; fa[t[x,r]]:=y; 53 t[y,l]:=t[x,r]; t[x,r]:=y; 54 pushup(y); 55 pushup(x); 56 end; 57 58 procedure splay(x:longint); 59 var y,z,k:longint; 60 begin 61 inc(top); q[top]:=x; 62 k:=x; 63 // while not isroot(k) do 64 while (t[fa[k],0]=k)or(t[fa[k],1]=k) do 65 begin 66 inc(top); q[top]:=fa[k]; 67 k:=fa[k]; 68 end; 69 while top>0 do 70 begin 71 pushdown(q[top]); 72 dec(top); 73 end; 74 75 // while not isroot(x) do 76 while (t[fa[x],0]=x)or(t[fa[x],1]=x) do 77 begin 78 y:=fa[x]; z:=fa[y]; 79 //if not isroot(y) then 80 if (t[fa[y],0]=y)or(t[fa[y],1]=y) then 81 begin 82 if (t[y,0]=x)xor(t[z,0]=y) then rotate(x) 83 else rotate(y); 84 end; 85 rotate(x); 86 end; 87 end; 88 89 procedure access(x:longint); 90 var last:longint; 91 begin 92 last:=0; 93 while x>0 do 94 begin 95 splay(x); t[x,1]:=last; pushup(x); 96 last:=x; x:=fa[x]; 97 end; 98 end; 99 100 function findroot(x:longint):longint; 101 var k:longint; 102 begin 103 access(x); splay(x); 104 k:=x; 105 while t[k,0]<>0 do k:=t[k,0]; 106 exit(k); 107 end; 108 109 procedure makeroot(x:longint); 110 begin 111 access(x); splay(x); rev[x]:=rev[x] xor 1; 112 end; 113 114 procedure link(x,y:longint); 115 begin 116 makeroot(x); fa[x]:=y; 117 end; 118 119 procedure cut(x,y:longint); 120 begin 121 makeroot(x); access(y); splay(y); t[y,0]:=0; fa[x]:=0; 122 end; 123 124 procedure update(l,r:longint;var p:longint;x:longint); 125 var mid:longint; 126 begin 127 inc(cnt); c[cnt]:=c[p]; 128 p:=cnt; inc(c[p,2]); 129 if l=r then exit; 130 mid:=(l+r)>>1; 131 if x<=mid then update(l,mid,c[p,0],x) 132 else update(mid+1,r,c[p,1],x); 133 end; 134 135 function query(p1,p2,l,r,x:longint):longint; 136 var mid:longint; 137 begin 138 if r=x then exit(c[p2,2]-c[p1,2]); 139 mid:=(l+r)>>1; 140 if x<=mid then exit(query(c[p1,0],c[p2,0],l,mid,x)) 141 else exit(c[c[p2,0],2]-c[c[p1,0],2]+query(c[p1,1],c[p2,1],mid+1,r,x)); 142 end; 143 144 begin 145 assign(input,'data.in'); reset(input); 146 assign(output,'bzoj3514.out'); rewrite(output); 147 readln(n,m,k,tp); 148 fillchar(b,sizeof(b),$1f); 149 for i:=1 to m do 150 begin 151 readln(x[i],y[i]); 152 if x[i]=y[i] then a[i]:=i 153 else 154 begin 155 if findroot(x[i])=findroot(y[i]) then 156 begin 157 makeroot(x[i]); access(y[i]); splay(y[i]); 158 tmp:=mx[y[i]]; 159 a[i]:=tmp-n; 160 cut(x[tmp-n],tmp); cut(tmp,y[tmp-n]); 161 b[n+i]:=i; mx[n+i]:=n+i; 162 link(x[i],i+n); link(i+n,y[i]); 163 end 164 else 165 begin 166 b[n+i]:=i; mx[n+i]:=n+i; 167 link(x[i],i+n); link(i+n,y[i]); 168 end; 169 end; 170 171 end; 172 //for i:=1 to m do writeln(a[i]); 173 for i:=1 to m do 174 begin 175 root[i]:=root[i-1]; 176 update(0,m,root[i],a[i]); 177 end; 178 for i:=1 to k do 179 begin 180 readln(l,r); 181 if tp=1 then 182 begin 183 l:=l xor lastans; 184 r:=r xor lastans; 185 end; 186 lastans:=n-query(root[l-1],root[r],0,m,l-1); 187 writeln(lastans); 188 end; 189 190 close(input); 191 close(output); 192 end.
null