bzoj 1095[ZJOI2007]Hide 捉迷藏

Posted Troy Ricardo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1095[ZJOI2007]Hide 捉迷藏相关的知识,希望对你有一定的参考价值。

题目链接:

  TP

 

题解:

  样例好良心,调样例3h一A……

  细节好多……诸如没完没了的pop和push……搞得头都大了。

  同情zzh……调了整一天了。

  动态点分治裸题……果然每个“裸题”打起来都跟shi一样。

题目:

  

  1 #define Troy
  2 #define inf 0x7fffffff
  3 
  4 #include <bits/stdc++.h>
  5 
  6 using namespace std;
  7 
  8 inline int read(){
  9     int s=0,k=1;char ch=getchar();
 10     while(ch<0|ch>9)    ch==-?k=-1:0,ch=getchar();
 11     while(ch>47&ch<=9)    s=s*10+(ch^48),ch=getchar();
 12     return k*s;
 13 }
 14 
 15 const int N=1e5+5;
 16 
 17 struct edges{
 18     int v;edges *last;
 19 }edge[N<<1],*head[N];int cnt;
 20 
 21 inline void push(int u,int v){
 22     edge[++cnt]=(edges){v,head[u]};head[u]=edge+cnt;
 23 }
 24 
 25 int n,m,f[N][21],deep[N],bit[21];
 26 
 27 inline void dfs(int x){
 28     for(int i=1;bit[i]<=deep[x];++i)
 29         f[x][i]=f[f[x][i-1]][i-1];
 30     for(edges *i=head[x];i;i=i->last)   if(i->v!=f[x][0]){
 31         deep[i->v]=deep[x]+1;
 32         f[i->v][0]=x;
 33         dfs(i->v);
 34     }
 35 }
 36 
 37 inline int lca(int x,int y){
 38     int ret=deep[x]+deep[y];    
 39     if(deep[x]<deep[y]) swap(x,y);
 40     int t=deep[x]-deep[y];
 41     for(int i=0;t;++i)
 42         if(bit[i]&t)    t^=bit[i],x=f[x][i];
 43     if(x!=y){
 44         for(int i=16;~i;--i)
 45             if(f[x][i]!=f[y][i])
 46                 x=f[x][i],y=f[y][i];
 47         x=f[x][0];    
 48     }
 49     return ret-(deep[x]<<1);
 50 }
 51 
 52 priority_queue<int,vector<int>,less<int> > q[N][2],e[N][2],ans,anse;
 53 int size[N],heavy[N],top,tot,root,lastans[N],lasttop[N],fat[N];
 54 bool vis[N];
 55 
 56 
 57 inline void dfs(int x,int fa){
 58     size[x]=1;
 59     heavy[x]=0;
 60     for(edges *i=head[x];i;i=i->last)   if(!vis[i->v]&&i->v!=fa){
 61         dfs(i->v,x);
 62         size[x]+=size[i->v];
 63         heavy[x]=max(heavy[x],size[i->v]);
 64     }heavy[x]=max(heavy[x],tot-size[x]);
 65     if(heavy[x]<top)    top=heavy[x],root=x;
 66 }
 67 
 68 inline void build(int x,int fa,int grand){
 69     q[grand][0].push(lca(x,fat[grand]));
 70     size[x]=1;
 71     for(edges *i=head[x];i;i=i->last)   if(!vis[i->v]&&i->v!=fa)
 72         build(i->v,x,grand),size[x]+=size[i->v];
 73 }
 74 
 75 inline void build(int x,int fa){
 76     top=inf;
 77     dfs(x,x);
 78     vis[x=root]=true;
 79     dfs(x,x);    
 80     fat[x]=fa;
 81     build(x,x,x);
 82     for(edges *i=head[x];i;i=i->last)if(vis[i->v]^1){
 83         tot=size[i->v];
 84         build(i->v,x);
 85         if(q[root][0].empty()^1)
 86             q[x][1].push(lasttop[root]=q[root][0].top());
 87     }
 88     if(!q[x][1].empty()){
 89         int a1=q[x][1].top();
 90         q[x][1].pop();
 91         ans.push(lastans[x]=a1+(q[x][1].empty()?0:q[x][1].top()));
 92         q[x][1].push(a1);
 93     }
 94     root=x;
 95 }
 96 
 97 inline void putans(){
 98     while(!ans.empty()&&!anse.empty()){
 99         if(ans.top()==anse.top())
100             ans.pop(),anse.pop();
101         else    break;
102     } 
103     if(tot<=1){
104         printf("%d\n",tot-1);
105     }else
106         printf("%d\n",ans.top());
107 }
108 
109 inline void clear(int x,bool k){
110     while(!q[x][k].empty()&&!e[x][k].empty()&&q[x][k].top()==e[x][k].top())
111         q[x][k].pop(),e[x][k].pop();
112 }
113 
114 inline void erase(int x,int s,int er){
115     int now=-1;
116     if(fat[x]){
117         if(vis[er])
118             e[x][0].push(lca(er,fat[x]));        
119         else
120             q[x][0].push(lca(er,fat[x]));
121         clear(x,0);
122         erase(fat[x],x,er);
123     }
124     if(s)  {
125         if(q[s][0].empty()^1)
126             now=q[s][0].top();
127         if(lasttop[s]!=now){
128             if(lasttop[s]!=-1)
129                 e[x][1].push(lasttop[s]);
130             if(now!=-1)
131                 q[x][1].push(now);
132         }else   return;
133         lasttop[s]=now; 
134     }
135     clear(x,1);
136     now=-1;
137     if(q[x][1].empty()^1){
138         int a1=q[x][1].top();
139         q[x][1].pop();
140         clear(x,1);
141         if(q[x][1].empty()^1)
142             now=a1+q[x][1].top();
143         else  if(!vis[x])  now=a1;
144         q[x][1].push(a1);
145     }
146     if(lastans[x]!=now){
147         if(lastans[x]!=-1)
148             anse.push(lastans[x]);
149         if(now!=-1)
150             ans.push(now);
151     }lastans[x]=now;
152 }
153 
154 inline void update(int x){
155     vis[x]^=1;
156     if(vis[x])  --tot;
157     else    ++tot;
158     erase(x,0,x);
159 }
160 
161 int main(){
162     n=read();
163     register int i;
164     for(i=1;i^n;++i){
165         int a=read(),b=read();
166         push(a,b),push(b,a);
167     }
168     for(i=0;i^21;++i)   bit[i]=1<<i;
169     memset(lastans,-1,sizeof(lastans));
170     memset(lasttop,-1,sizeof(lasttop));
171     dfs(1);tot=n;
172     build(1,0);
173     memset(vis,0,sizeof(vis));
174     tot=n;
175     m=read();
176     while(m--){
177         char opt[2];
178         scanf("%s",opt);
179         if(opt[0]==G) putans();
180         else    update(read());
181     }
182 }

 

以上是关于bzoj 1095[ZJOI2007]Hide 捉迷藏的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1095: [ZJOI2007]Hide 捉迷藏

BZOJ1095[ZJOI2007]Hide 捉迷藏 动态树分治+堆

[bzoj1095][ZJOI2007]Hide 捉迷藏 点分树,动态点分治

bzoj 1095[ZJOI2007]Hide 捉迷藏

Bzoj1095 [ZJOI2007]Hide 捉迷藏

bzoj千题计划252:bzoj1095: [ZJOI2007]Hide 捉迷藏