# BZOJ 1095 ZJOI2007 Hide 捉迷藏 动态树分治+堆

《珍爱生命远离STL可是我还是可耻地用了STL系列》

↑别听这傻瓜瞎说这货被STL卡了一天QAQ

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;
struct Priority_Queue{
priority_queue<int> heap,delmark;
void Insert(int x)
{
heap.push(x);
}
void Erase(int x)
{
delmark.push(x);
}
void Pop()
{
while( delmark.size() && heap.top()==delmark.top() )
heap.pop(),delmark.pop();
heap.pop();
}
int Top()
{
while( delmark.size() && heap.top()==delmark.top() )
heap.pop(),delmark.pop();
return heap.top();
}
int Second_Top()
{
int temp=Top();Pop();
int re=Top();Insert(temp);
return re;
}
int Size()
{
return heap.size()-delmark.size();
}
}s1[M],s2[M],ans;

struct abcd{
int to,next;
bool ban;
}table[M<<1];
int n,m,cnt;
int fa[M];
bool status[M];
int log_2[M<<1],dpt[M],pos[M],a[M<<1][20],T;
{
table[++tot].to=y;
}
int Get_Size(int x,int from)
{
int i,re=1;
{
if(table[i].ban||table[i].to==from)
continue;
re+=Get_Size(table[i].to,x);
}
return re;
}
int Get_Centre_Of_Gravity(int x,int from,int size,int &cg)
{
int i,re=1,flag=true;
{
if(table[i].ban||table[i].to==from)
continue;
int temp=Get_Centre_Of_Gravity(table[i].to,x,size,cg);
if(temp<<1>size)
flag=false;
re+=temp;
}
if(size-re<<1>size)
flag=false;
if(flag) cg=x;
return re;
}
void DFS(int x,int from,int dpt,Priority_Queue &s)
{
int i;
s.Insert(dpt);
{
if(table[i].ban||table[i].to==from)
continue;
DFS(table[i].to,x,dpt+1,s);
}
}
void Insert(Priority_Queue &s)
{
if(s.Size()>=2)
{
int temp=s.Top()+s.Second_Top();
ans.Insert(temp);
}
}
void Erase(Priority_Queue &s)
{
if(s.Size()>=2)
{
int temp=s.Top()+s.Second_Top();
ans.Erase(temp);
}
}
int Tree_Divide_And_Conquer(int x)
{
int i,size,cg;size=Get_Size(x,0);
Get_Centre_Of_Gravity(x,0,size,cg);
s2[cg].Insert(0);
if(!table[i].ban)
{
table[i].ban=table[i^1].ban=true;
Priority_Queue s;
DFS(table[i].to,0,1,s);
int temp=Tree_Divide_And_Conquer(table[i].to);
fa[temp]=cg;s1[temp]=s;
s2[cg].Insert(s1[temp].Top());
}
Insert(s2[cg]);
return cg;
}
void DFS(int x,int from)
{
int i;
a[pos[x]=++T][0]=dpt[x]=dpt[from]+1;
if(table[i].to!=from)
{
DFS(table[i].to,x);
a[++T][0]=dpt[x];
}
}
int LCA_Depth(int x,int y)
{
x=pos[x];y=pos[y];
if(x>y) swap(x,y);
int L=log_2[y-x+1];
return min(a[x][L],a[y-(1<<L)+1][L]);
}
int Distance(int x,int y)
{
return dpt[x]+dpt[y]-2*LCA_Depth(x,y);
}
void Turn_On(int x)
{
int i;
Erase(s2[x]);
s2[x].Insert(0);
Insert(s2[x]);
for(i=x;fa[i];i=fa[i])
{
Erase(s2[fa[i]]);

if(s1[i].Size())
s2[fa[i]].Erase(s1[i].Top());

s1[i].Insert(Distance(fa[i],x));

if(s1[i].Size())
s2[fa[i]].Insert(s1[i].Top());

Insert(s2[fa[i]]);
}
}
void Turn_Off(int x)
{
int i;
Erase(s2[x]);
s2[x].Erase(0);
Insert(s2[x]);
for(i=x;fa[i];i=fa[i])
{
Erase(s2[fa[i]]);

if(s1[i].Size())
s2[fa[i]].Erase(s1[i].Top());

s1[i].Erase(Distance(fa[i],x));

if(s1[i].Size())
s2[fa[i]].Insert(s1[i].Top());

Insert(s2[fa[i]]);
}
}
int main()
{
int i,j,x,y;
char p[10];
cin>>n;cnt=n;
for(i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
}
Tree_Divide_And_Conquer(1);
DFS(1,0);
for(i=2;i<=T;i++)
log_2[i]=log_2[i>>1]+1;
for(j=1;j<=log_2[T];j++)
for(i=1;i+(1<<j)-1<=T;i++)
a[i][j]=min(a[i][j-1],a[i+(1<<j-1)][j-1]);
for(i=1;i<=n;i++)
status[i]=true;
cin>>m;
for(i=1;i<=m;i++)
{
scanf("%s",p);
if(p[0]=='G')
{
if(cnt<=1)
printf("%d\n",cnt-1);
else
printf("%d\n",ans.Top());
}
else
{
scanf("%d",&x);
if(status[x]==true)
{
--cnt;status[x]=false;
Turn_Off(x);
}
else
{
++cnt;status[x]=true;
Turn_On(x);
}
}
}
return 0;
}

• 本文已收录于以下专栏：

举报原因： 您举报文章：BZOJ 1095 ZJOI2007 Hide 捉迷藏 动态树分治+堆 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)