您的位置:首页 > 其它

[bzoj1095] [ZJOI2007]Hide 捉迷藏

2016-04-20 22:11 495 查看
  珍爱生命远离STL

  珍爱空间远离STL

T_T

  动态信息的点分治。

  如果没有修改的话记录一下最大值就好了。

  有修改的话就用堆= =

  详细题解见 http://blog.csdn.net/popoqqq/article/details/44461423

  脑子几度当机导致调了一晚上= =。。。最后还是swm大爷提醒下才调出来的= =。

  调优先队列的话空间很成问题。。无用节点能不加就不加。。最后刚好卡过去...

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=100023,inf=1000233333;
struct zs{
int too,pre;
}e[maxn<<1];int tot,last[maxn];
struct zs1{
int id,v;
};

int sz[maxn],mx[maxn],p[maxn],dis[maxn],mxd[maxn],num,rt,poi;
int v[maxn];
int f[21][maxn],dist[21][maxn];
priority_queue<zs1>q[maxn<<1];
int i,j,k,n,m;
bool gg[maxn],del[maxn];

int ra;char rx;
inline int read(){
rx=getchar(),ra=0;
while(rx<'0'||rx>'9')rx=getchar();
while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
}
inline void insert(int a,int b){
e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;
e[++tot].too=a,e[tot].pre=last[b],last[b]=tot;
}

bool operator <(zs1 a,zs1 b){return a.v<b.v;}
inline void clr0(){
while(!q[0].empty()&&v[q[0].top().id]!=q[0].top().v)q[0].pop();
}
inline void clr(int x){
while(!q[x].empty()&&gg[q[x].top().id])q[x].pop();
if(q[x].empty())q[x].push((zs1){0,-1});
}
inline void clr1(int x){
while(!q[x].empty()&&q[x].top().v!=q[q[x].top().id].top().v)q[x].pop();
}
inline zs1 getmx(int x){
clr(x);
return q[x].top();
}
inline zs1 getmx1(int x){
clr1(x);
return !q[x].empty()?q[x].top():(zs1){0,-1};
}
inline int getans(){
clr0();
return q[0].top().v;
}
inline int getsm(int x){
zs1 tmp=getmx1(x),tmp1;
if(tmp.v==-1)return !gg[x]?0:-1;
tmp=q[x].top(),q[x].pop();
while(!q[x].empty()&&(q[x].top().v!=q[q[x].top().id].top().v||q[x].top().id==tmp.id))q[x].pop();
tmp1=!q[x].empty()?q[x].top():(zs1){0,-1};
q[x].push(tmp);
if(tmp1.v==-1)return !gg[x]?tmp.v:0;
else return tmp.v+tmp1.v;
}

void getrt(int x,int fa){
sz[x]=mx[x]=1;
for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa&&!del[e[i].too])
getrt(e[i].too,x),sz[x]+=sz[e[i].too],mx[x]=max(mx[x],sz[e[i].too]);
mx[x]=max(mx[x],poi-mx[x]);
if(mx[x]<mx[rt])rt=x;
}
void getpoi(int x,int fa){
p[++num]=x;
for(int i=last[x];i;i=e[i].pre)if(e[i].too!=fa&&!del[e[i].too])
dis[e[i].too]=dis[x]+1,getpoi(e[i].too,x);
}
void work(int dep,int x,int precg){
int cg,i;int tmp=0;
getrt(x,rt=0),cg=rt;//printf("  cg:%d   precg:%d\n",cg,precg);
if(dep>1){
dis[x]=1,num=0,getpoi(x,precg);
for(i=1;i<=num;i++)q[cg+n].push((zs1){p[i],dis[p[i]]}),tmp=max(tmp,dis[p[i]]);
q[precg].push((zs1){cg+n,tmp});
}
mxd[cg]=dep,dis[cg]=0,del[cg]=1;

num=0,getpoi(cg,0);
for(i=1;i<=num;i++)f[dep][p[i]]=cg,dist[dep][p[i]]=dis[p[i]];
//,printf("   %d",p[i]);puts("");

for(i=last[cg];i;i=e[i].pre)if(!del[e[i].too])
poi=sz[e[i].too],work(dep+1,e[i].too,cg);
q[0].push((zs1){cg,v[cg]=getsm(cg)});
}
inline void modify(int x){
//    printf("modify:%d\n",x);
gg[x]^=1;int fa,tmp;
if(!gg[x]){
v[x]=getsm(x),q[0].push((zs1){x,v[x]});
for(i=mxd[x]-1;i;i--){
q[f[i+1][x]+n].push((zs1){x,dist[i][x]}),clr(f[i+1][x]+n),
fa=f[i][x];
if((tmp=q[f[i+1][x]+n].top().v)==dist[i][x])
q[fa].push((zs1){f[i+1][x]+n,tmp});
v[fa]=getsm(fa),q[0].push((zs1){fa,v[fa]});
}
}else{
v[x]=getsm(x),q[0].push((zs1){x,v[x]});
for(i=mxd[x]-1;i;i--)
fa=f[i][x],
q[fa].push((zs1){f[i+1][x]+n,getmx(f[i+1][x]+n).v}),
v[fa]=getsm(fa),q[0].push((zs1){fa,v[fa]});

}
clr0();
}
int main(){
mx[0]=inf;
n=read();
for(i=1;i<n;i++)insert(read(),read());
poi=n,work(1,1,0);
char s[23];
for(m=read();m;m--){
scanf("%s",s);
if(s[0]=='G')printf("%d\n",getans());else modify(read());
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: