bzoj 1095[ZJOI2007]Hide 捉迷藏
Posted Troy Ricardo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1095[ZJOI2007]Hide 捉迷藏相关的知识,希望对你有一定的参考价值。
题目链接:
题解:
样例好良心,调样例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 捉迷藏 动态树分治+堆