bzoj 1095: [ZJOI2007]Hide 捉迷藏
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于bzoj 1095: [ZJOI2007]Hide 捉迷藏的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ1095[ZJOI2007]Hide 捉迷藏 动态树分治+堆