码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-01-31 22:43:49      阅读:384      评论:0      收藏:0      [点我收藏+]

标签:proc   eset   cti   swap   down   div   线段树   tmp   read   

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

 

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

标签:proc   eset   cti   swap   down   div   线段树   tmp   read   

原文地址:http://www.cnblogs.com/myx12345/p/6359218.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!