GERALD07 enhanced version: lct, Chairman of the tree, side of the point

Description: No N points of M to FIG edges, the number of queries reservation FIG Unicom block [l, r] FIG edges when numbering.

Portal .

 

lct so god things a solution to a problem is not how to write the line? ? ?

Fairy ideas ah.

In fact, not difficult but certainly not easy to think of.

We consider what the answer yes.

First, beginning with n points are Unicom block, then you can not even make a few side Unicom block is reduced.

How to reduce it? Is the number of intervals of the top edge of the spanning tree. Because if it is not on the side of the spanning tree, the spanning tree on some sides and a ring without the combined block Unicom.

How to determine the side on the inner side is not the interval spanning tree it? It is determined based on the front side and there form a ring.

So we first side put together, even when we found the first side of the piece had been connected to these two points, this edge can replace occur edges.

If it is the substituent that edge interval of not, then this edge in the spanning tree.

So come on an LCT, the maintenance side of the maximum number of points on the line, will ask to be replaced before the edge of each side of the insert, there is an array lst years.

Then for each set of query, asking the question becomes at the array lst lst subscript value of less than l, within a few [l, r].

Chairman tree with maintenance just fine.

Remember this line of thinking.

 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 int c[400005][2],f[400005],w[400005],n,m,k,opt,fid[400005],lst[200005],q[400005];
 5 int x[200005],y[200005],ans,rt[200005],v[5000005],t[5000005][2],lz[400005],cnt;
 6 int find(int p){return fid[p]==p?p:fid[p]=find(fid[p]);}
 7 #define lc c[p][0]
 8 #define rc c[p][1]
 9 bool not_root(int p){return c[f[p]][0]==p||c[f[p]][1]==p;}
10 void rev(int p){lc^=rc^=lc^=rc;lz[p]^=1;}
11 void down(int p){if(lz[p])rev(lc),rev(rc),lz[p]=0;}
12 void up(int p){w[p]=min(p>n?p:1234567890,min(w[lc],w[rc]));}
13 void rotate(int p){
14     int fa=f[p],gr=f[fa],dir=c[fa][1]==p,br=c[p][!dir];
15     if(not_root(fa))c[gr][c[gr][1]==fa]=p; c[p][!dir]=fa; c[fa][dir]=br;
16     f[p]=gr; f[fa]=p; f[br]=fa; up(fa);
17 }
18 void splay(int p){
19     int res=p,top=0;q[++top]=p;
20     while(not_root(res))q[++top]=res=f[res];
21     while(top)down(q[top--]);
22     while(not_root(p)){
23         int fa=f[p],gr=f[fa];
24         if(not_root(fa))rotate(c[fa][1]==p^c[gr][1]==fa?fa:p);
25         rotate(p);
26     }
27     up(p);
28 }
29 void access(int p){for(int y=0;p;p=f[y=p])splay(p),rc=y,up(p);}
30 void make_root(int p){access(p);splay(p);rev(p);}
31 void split(int x,int y){make_root(x);access(y);splay(y);}
32 void cut(int x,int y){split(x,y);f[x]=c[y][0]=0;up(y);}
33 void link(int x,int y){make_root(x);f[x]=y;up(y);}
34 void build(int &p,int cpy,int adx,int l=0,int r=m){
35     if(!p)p=++cnt;
36     if(l==r){v[p]=v[cpy]+1;return;}
37     if(adx<=l+r>>1)build(t[p][0],t[cpy][0],adx,l,l+r>>1),t[p][1]=t[cpy][1];
38     else build(t[p][1],t[cpy][1],adx,(l+r>>1)+1,r),t[p][0]=t[cpy][0];
39     v[p]=v[t[p][0]]+v[t[p][1]];//printf("%d %d %d\n",l,r,v[p]);
40 }
41 int ask(int p1,int p2,int l,int r,int cl=0,int cr=m){//printf("%d %d %d %d\n",cl,cr,v[p2],v[p1]);
42     if(!(v[p2]-v[p1]))return 0;
43     if(l<=cl&&cr<=r)return v[p2]-v[p1];
44     return (l<=cl+cr>>1?ask(t[p1][0],t[p2][0],l,r,cl,cl+cr>>1):0)+(r>cl+cr>>1?ask(t[p1][1],t[p2][1],l,r,(cl+cr>>1)+1,cr):0);
45 }
46 int main(){w[0]=1234567890;
47     scanf("%d%d%d%d",&n,&m,&k,&opt);
48     for(int i=1;i<=n;++i)fid[i]=i;
49     for(int i=1;i<=m;++i){
50         scanf("%d%d",&x[i],&y[i]);
51         if(x[i]==y[i])lst[i]=i;
52         else if(find(x[i])!=find(y[i]))fid[fid[x[i]]]=fid[y[i]],link(x[i],n+i),link(n+i,y[i]);
53         else split(x[i],y[i]),lst[i]=w[y[i]]-n,cut(lst[i]+n,x[lst[i]]),cut(lst[i]+n,y[lst[i]]),
54             link(x[i],n+i),link(y[i],n+i);
55         build(rt[i],rt[i-1],lst[i]);//printf("%d\n",lst[i]);
56     }
57     for(int i=1,l,r;i<=k;++i){
58         scanf("%d%d",&l,&r);
59          if (opt) s ^ = year = r ^ years;
60          years = n-ask (rt [l- 1 ] rt [r] 0 , L 1 );
61          printf ( " % d \ n " , year);
62      }
 63 }
View Code

 

Guess you like

Origin www.cnblogs.com/hzoi-DeepinC/p/11566956.html