【BZOJ 1095】 [ZJOI2007]Hide 捉迷藏
神犇们的一眼码农题 我做了2.5天!!!!!!!!!!!!!!!!!!!!!!!!!!
不想写题解了 但网上的没有几个能看 有留言的话就在写!
不少题解用LCA求距离 然而我 TLE+MLE
于是用一种奇怪的方法 vector来记录距离
再加上奇怪的卡内存姿势终于过掉了!
/**************************************************************
Problem: 1095
User: sxb_201
Language: C++
Result: Accepted
Time:10332 ms
Memory:143244 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define MAXN 100010
using namespace std;
struct H
{
priority_queue<int> A,B;
int size()
{
return A.size()-B.size();
}
void push(int x)
{
A.push(x);
}
void out(int x)
{
B.push(x);
while(!B.empty()&&B.top()==A.top()) B.pop(),A.pop();
}
int top_1()
{
while(!B.empty()&&B.top()==A.top()) B.pop(),A.pop();
return A.top();
}
int top_2()
{
int tmp_1,tmp_2;
tmp_1=top_1();
A.pop();
tmp_2=top_1();
A.push(tmp_1);
return tmp_2;
}
}Q[MAXN],P[MAXN],ANS;int cnt=0;
int g[MAXN],num[MAXN*2],nnext[MAXN*2],tot;
inline void Add(int x,int y){tot++;nnext[tot]=g[x];g[x]=tot;num[tot]=y;}
int fa_root[MAXN],fa_tmp[MAXN],fa_son[MAXN];
vector<int>fa_num[MAXN];
int n,m;
int sum,root,max_son,size[MAXN];
bool b[MAXN],is_black[MAXN];
int mmax[MAXN];
inline void Get_Root(int x,int fa,int lenth,int rt,int frt)
{ //cerr<<x<<' '<<fa<<endl;
Q[rt].push(lenth);
fa_num[x].push_back(lenth);
// printf("%d\n",lenth);
int son=0;
size[x]=1;
for(int i=g[x];i;i=nnext[i])
if(num[i]!=fa&&!b[num[i]])
{
Get_Root(num[i],x,lenth+1,rt,frt);
size[x]+=size[num[i]];
son=max(son,size[num[i]]);
}
son=max(son,sum-size[x]); //cout<<max_son<<' '<<size[x]<<endl;
if(son<max_son)
{
max_son=son;
root=x;
fa_root[root]=frt;
fa_son[root]=rt;
}
}
inline void Up(int x)
{
if(mmax[x]!=0) ANS.out(mmax[x]);
if(P[x].size()<2){mmax[x]=0;return ;}
mmax[x]=P[x].top_1()+P[x].top_2();
//cout<<x<<' '<<mmax[x]<<endl;
ANS.push(mmax[x]);
}
void Dfs_Size(int x,int fa)
{
// cerr<<x<<endl;
size[x]=1;
for(int i=g[x];i;i=nnext[i])
if(!b[num[i]]&&num[i]!=fa)
{
Dfs_Size(num[i],x);
size[x]+=size[num[i]];
}
}
void Do(int x)
{
// cerr<<x<<endl;
b[x]=true;
for(int i=g[x];i;i=nnext[i])
if(!b[num[i]])
{
root=num[i];
Dfs_Size(num[i],-1);
sum=size[num[i]];//cout<<sum<<endl;
max_son=n+1;
Get_Root(num[i],-1,1,++cnt,x);
// printf("%d %d\n",sum,max_son);
P[x].push(Q[cnt].top_1()); //cout<<x<<' '<<num[i]<<endl;
Do(root);
}
P[x].push(0);
Up(x);
}
void Change(int x,int lenth,bool is_add)
{
// cout<<x<<' '<<lenth<<' '<<is_add<<endl;
int fa=fa_root[x],son=fa_son[x];// cout<<fa<<' '<<son<<' '<<Q[son].size()<<endl;
if(is_add==true)
{
if(Q[son].size()==0||Q[son].top_1()<lenth)
{
if(Q[son].size()!=0) P[fa].out(Q[son].top_1());
Q[son].push(lenth);
P[fa].push(lenth);
}
else
Q[son].push(lenth);
}
else
{
if(Q[son].top_1()==lenth)
{
P[fa].out(lenth);
Q[son].out(lenth);
if(Q[son].size()!=0)
P[fa].push(Q[son].top_1());
// cout<<fa<<' '<<lenth<<' '<<Q[son].top_1()<<endl;
}
else
Q[son].out(lenth);
}//cout<<fa<<endl;
// cout<<fa<<' '<<mmax[fa]<<endl;
Up(fa);
// cout<<mmax[fa]<<endl;
// cout<<'*'<<ANS.top_1()<<endl;
}
int main()
{
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d %d",&x,&y);
Add(x,y);
Add(y,x);
} // cerr<<tot;
max_son=n+1; sum=n;
Do(1);
int num_black=n;
for(int i=1;i<=n;i++) is_black[i]=true;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
char c;getchar();c=getchar();
if(c=='G')
{
if(num_black==0) printf("-1\n");
else if(num_black==1) printf("0\n");
else printf("%d\n",ANS.top_1());
}
else
{
int x;scanf("%d",&x);
if(is_black[x]==true)
{
num_black--;
is_black[x]=false;
P[x].out(0);
}
else
{
num_black++;
is_black[x]=true;
P[x].push(0);
}
int tmp=fa_num[x].size();
int nn=1;
for(int i=x;fa_root[i]!=0;i=fa_root[i],nn++) Change(i,fa_num[x][tmp-nn],is_black[x]);
Up(x);
}
}
}