您的位置:首页 > 其它

【BZOJ3514】Codechef MARCH14 GERALD07加强版(LCT)

2017-01-31 22:25 477 查看

题意: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

; 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.

[p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: