# BZOJ1095 动态点分治

https://www.lydsy.com/JudgeOnline/problem.php?id=1095

#include<cstdio>
#include<algorithm>
#include<queue>
#include<iostream>
#define re register
#define rep(i,s,t) for(register int i=s;i<=t;++i)
#define _rep(i,s,t) for(register int i=s;i>=t;--i)
#define Rep(i,s,t) for(register int i=s;i<t;++i)
#define go(x) for(register int e=las[x];e;e=nxt[e])
using namespace std;
namespace IO{
#define gc getchar()
#define pc(x) putchar(x)
x=0;int f=1;char ch=gc;while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=gc;}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=gc;x*=f;return;
}
template<typename T>inline void write(T x=0){
T wr[51];wr[0]=0;if(x<0)pc('-'),x=-x;if(!x)pc(48);
while(x)wr[++wr[0]]=x%10,x/=10;while(wr[0])pc(48+wr[wr[0]--]);return;
}
}
using IO::write;
const int N=2e5+11,inf=1<<30;
int n,m,tot,x,y,sum,rt;
int nxt[N],las[N],to[N],up[N][18],dep[N];
int sz[N],mx[N],fa[N];
bool vis[N],light[N];
struct heap{
priority_queue<int>A,B;
inline void push(int x){
A.push(x);
}
inline void erase(int x){
B.push(x);
}
inline int top(){
for(;B.size()&&A.top()==B.top();)
A.pop(),B.pop();
if(A.size())
return A.top();
return 0;
}
inline void pop(){
for(;B.size()&&A.top()==B.top();)
A.pop(),B.pop();
if(A.size())
A.pop();
}
inline int sec(){
re int tmp=top();
pop();
re int ret=top();
push(tmp);
return ret;
}
inline int size(){
return A.size()-B.size();
}
}c[N>>1],f[N>>1],ans;
inline void ins(heap &s){
//if(s.size()>1)
//    printf("ins:%d %d\n",s.top(),s.sec());
if(s.size()>1)
ans.push(s.top()+s.sec());
}
inline void del(heap &s){
//if(s.size()>1)
//    printf("del:%d %d\n",s.top(),s.sec());
if(s.size()>1)
ans.erase(s.top()+s.sec());
}
nxt[++tot]=las[x],las[x]=tot,to[tot]=y;
}
inline void dfs(int x,int anc){
up[x][0]=anc;
rep(i,1,17)
up[x][i]=up[up[x][i-1]][i-1];
go(x){
if(to[e]==anc)continue;
dep[to[e]]=dep[x]+1;
dfs(to[e],x);
}
}
inline int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
int t=dep[x]-dep[y];
_rep(i,17,0)
if(t>>i&1)
x=up[x][i];
if(x==y)
return x;
_rep(i,17,0)
if(up[x][i]!=up[y][i])
x=up[x][i],y=up[y][i];
return up[x][0];
}
inline int dis(int x,int y){
return dep[x]+dep[y]-2*dep[lca(x,y)];
}
inline void findrt(int x,int anc){
sz[x]=1,mx[x]=0;
go(x){
if(vis[to[e]]||to[e]==anc)continue;
findrt(to[e],x);
sz[x]+=sz[to[e]];
mx[x]=max(mx[x],sz[to[e]]);
}
mx[x]=max(mx[x],sum-sz[x]);
if(mx[x]<mx[rt])
rt=x;
}
inline void work(int x,int anc,int R){
//printf("%d %d %d\n",x,anc,R);
f[rt].push(dis(x,R));
go(x){
if(to[e]==anc||vis[to[e]])continue;
work(to[e],x,R);
}
}
inline void build_tree(int x,int anc){
fa[x]=anc,vis[x]=1,c[x].push(0),work(x,0,anc);
//printf("%d %d\n",x,anc);
int v;
go(x){
if(vis[to[e]])continue;
rt=0,mx[0]=inf,sum=sz[to[e]],
findrt(to[e],x),v=rt,build_tree(rt,x);
c[x].push(f[v].top());
}
ins(c[x]);
}
inline void on(int x){
del(c[x]),c[x].erase(0),ins(c[x]);
for(re int i=x;i;i=fa[i]){
del(c[fa[i]]);
if(f[i].size())
c[fa[i]].erase(f[i].top());
f[i].erase(dis(x,fa[i]));
if(f[i].size())
c[fa[i]].push(f[i].top());
ins(c[fa[i]]);
}
}
inline void off(int x){
del(c[x]),c[x].push(0),ins(c[x]);
for(re int i=x;i;i=fa[i]){
del(c[fa[i]]);
if(f[i].size())
c[fa[i]].erase(f[i].top());
f[i].push(dis(x,fa[i]));
if(f[i].size())
c[fa[i]].push(f[i].top());
ins(c[fa[i]]);
}
}
int main(){
gi(n);
rep(i,2,n){
gii(x,y);
}
dfs(1,0),mx[0]=inf,rt=0,sum=n,
findrt(1,0),build_tree(rt,0);
int num=n,q;char ch[10];
gi(q);
for(;q--;){
scanf("%s",ch);
if(ch[0]=='C'){
gi(x);
if(light[x])
off(x),++num;
else
on(x),--num;
light[x]^=1;
}
else
printf("%d\n",num<=1?num-1:ans.top());
}
return 0;
}
code

posted @ 2018-06-23 17:18  Stump  阅读(110)  评论(0编辑  收藏