bzoj 1095: [ZJOI2007]Hide 捉迷藏

2016-06-23

这种题果然不是我这种智商的人可以做的。。

网上两种做法,一种把树转化成括号序列  再用线段树维护好几个量(简直太神啦。。可惜蒟蒻看不懂)

还有一种是 先把树每次点分治的重心连向上一层的重心,重建一棵树。再来三个堆,

C.每个重心存所有子树到其距离
B.每个重心存各个子树最大值,即子结点堆C的最大值
A.全局一个堆,维护答案最大值,存每个堆B的最大值和次大值之和
由于重建后树高log(n),所以时间可以保证。
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cstdlib>
  6 #include<queue>
  7 #define M 100005
  8 #define ll long long
  9 using namespace std;
 10 ll read()
 11 {
 12     char ch=getchar();
 13     ll x=0,f=1;
 14     for(;ch<'0'||ch>'9';ch=getchar())
 15       if(ch=='-')
 16         f=-1;
 17     for(;ch>='0'&&ch<='9';ch=getchar())
 18       x=x*10+ch-'0';
 19     return x*f;
 20 }
 21 struct data
 22 {
 23     priority_queue<int> A,B;
 24     void push(int x)
 25       {
 26           A.push(x);
 27       }
 28     void shan(int x)
 29       {
 30           B.push(x);
 31       }
 32     void pop()
 33       {
 34         for(;B.size()&&A.top()==B.top();A.pop(),B.pop());
 35           if(A.size())
 36             A.pop();
 37       }
 38     int top()
 39       {
 40           for(;B.size()&&A.top()==B.top();A.pop(),B.pop());
 41           if(!A.size())
 42             return 0;
 43           return A.top();
 44       }
 45     int size()
 46       {
 47           return A.size()-B.size();
 48       }
 49     int stop()
 50       {
 51           if(size()<2)
 52             return 0;
 53           int x=top();
 54           pop();
 55           int y=top();
 56           push(x);
 57           return y;
 58       }
 59 }A,B[M],C[M];
 60 int bin[M],Log[2*M],cnt,next[2*M],head[M],u[2*M],n,st[2*M][22],deep[M],sum,size[M],f[M],G;
 61 bool yy[M];
 62 int fa[M],col[M],pos[M],T;
 63 void jia(int a1,int a2)
 64 {
 65     next[++cnt]=head[a1];
 66     head[a1]=cnt;
 67     u[cnt]=a2;
 68 }
 69 void dfs(int x,int F)
 70 {
 71     st[++T][0]=deep[x];
 72     pos[x]=T;
 73     for(int i=head[x];i;i=next[i])
 74       if(u[i]!=F)
 75         {
 76           deep[u[i]]=deep[x]+1;
 77             dfs(u[i],x);
 78             st[++T][0]=deep[x];
 79         }
 80 }
 81 void getroot(int x,int F)
 82 {
 83     size[x]=1;
 84     f[x]=0;
 85     for(int i=head[x];i;i=next[i])
 86       if(!yy[u[i]]&&u[i]!=F)
 87         {
 88             getroot(u[i],x);
 89             f[x]=max(f[x],size[u[i]]);
 90             size[x]+=size[u[i]];
 91         }
 92     f[x]=max(f[x],sum-size[x]);
 93     if(f[x]<f[G])
 94       G=x;
 95 }
 96 void fen(int x)
 97 {
 98     yy[x]=1;
 99     for(int i=head[x];i;i=next[i])
100       if(!yy[u[i]])
101         {
102             G=0;
103             sum=size[u[i]];
104             getroot(u[i],x);
105             fa[G]=x;
106             fen(G);
107         }
108 }
109 int stt(int x,int y)
110 {
111     int q=pos[x],w=pos[y];
112     if(q>w)
113       swap(q,w);
114     int t=Log[w-q+1];
115     return min(st[q][t],st[w-bin[t]+1][t]);
116 }
117 void kai(int x,int y)
118 {
119     if(x==y)
120       {
121           B[x].push(0);
122           if(B[x].size()==2)
123             A.push(B[x].top());
124       }
125     if(!fa[x])
126       return;
127     int f1=fa[x],D=deep[f1]+deep[y]-2*stt(f1,y),E=C[x].top();
128     C[x].push(D);
129     if(D>E)
130       {
131           int a1=B[f1].top()+B[f1].stop(),si=B[f1].size();
132           if(E)
133             B[f1].shan(E);
134           B[f1].push(D);
135           int a2=B[f1].top()+B[f1].stop();
136           if(a2>a1)
137             {
138                 if(si>=2)
139                   A.shan(a1);
140                 if(B[f1].size()>=2)
141                   A.push(a2);
142           }
143       }
144     kai(f1,y);
145 }
146 void guan(int x,int y)
147 {
148     if(x==y)
149       {
150           if(B[x].size()==2)
151             A.shan(B[x].top());
152           B[x].shan(0);
153       }
154     if(!fa[x])
155       return;
156     int f1=fa[x],D=deep[f1]+deep[y]-2*stt(f1,y),E=C[x].top();
157     C[x].shan(D);
158     if(D==E)
159       {
160           int a1=B[f1].top()+B[f1].stop(),si=B[f1].size();
161           B[f1].shan(D);
162           if(C[x].top())
163             B[f1].push(C[x].top());
164           int a2=B[f1].top()+B[f1].stop();
165           if(a2<a1)
166             {
167                 if(si>=2)
168                   A.shan(a1);
169                 if(B[f1].size()>=2)
170                   A.push(a2);
171           }
172       }
173     guan(f1,y);
174 }
175 int main()
176 {
177     n=read();
178     for(int i=1;i<n;i++)
179       {
180           int a1=read(),a2=read();
181           jia(a1,a2);
182           jia(a2,a1);
183       }
184     bin[0]=1;
185     for(int i=1;i<=20;i++)
186       bin[i]=bin[i-1]*2;
187     Log[0]=-1;
188     for(int i=1;i<=200000;i++)
189       Log[i]=Log[i/2]+1;
190     dfs(1,0);
191     for(int i=T;i;i--)
192       for(int j=1;j<=19;j++)
193         if(i+bin[j]-1<=T)
194           st[i][j]=min(st[i][j-1],st[i+bin[j-1]][j-1]);
195     f[0]=0x7fffffff;
196     sum=n;
197     getroot(1,0);
198     fen(G);
199     for(int i=1;i<=n;i++)
200       col[i]=1;
201     for(int i=1;i<=n;i++)
202       C[i].push(0);
203     for(int i=1;i<=n;i++)
204        kai(i,i);
205     char ch[10];
206     int qqq=n;
207     int m=read();
208     for(;m;m--)
209       {
210           scanf("%s",ch);
211           if(ch[0]=='G')
212             {
213                 if(qqq<=1)
214                   printf("%d\n",qqq-1);
215                 else
216                   printf("%d\n",A.top());
217           }
218         else
219           {
220               int a1=read();
221               if(col[a1])
222                 {
223                     qqq--;
224                     guan(a1,a1);
225                 }
226             else
227               {
228                   qqq++;
229                   kai(a1,a1);
230               }
231             col[a1]^=1;
232           }
233       }
234     return 0;
235 }

 

 

 

posted @ 2016-06-23 17:28  xiw5  阅读(373)  评论(0编辑  收藏  举报