BZOJ1095: [ZJOI2007]捉迷藏 【树上距离->括号序列+线段树】

版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/C20181220_xiang_m_y/article/details/88863317

题解戳这里

#include<cstdio>
#include<cctype>
#include<algorithm>
#define maxn 300005
#define LL long long
using namespace std;
char cb[1<<15],*cs,*ct;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
template<class T>inline void read(T &a){
	char c;bool f=0;while(!isdigit(c=getc())) if(c=='-') f=1;
	for(a=c-'0';isdigit(c=getc());a=a*10+c-'0'); if(f) a=-a;
}
const int inf = 0x3f3f3f3f;
int n,m,s[maxn],c[maxn],sz,pos[maxn];
int fir[maxn],nxt[maxn],to[maxn],tot;
inline void line(int x,int y){nxt[++tot]=fir[x];fir[x]=tot;to[tot]=y;}
void dfs(int u){
	s[++sz]=-6;//(
	s[++sz]=u,pos[u]=sz;
	for(int i=fir[u];i;i=nxt[i]) if(!pos[to[i]]) dfs(to[i]);
	s[++sz]=-9;//)
}
struct node{
	int a,b,l1,l2,r1,r2,dis;
	inline void init(int x){
		a=b=0,l1=l2=r1=r2=dis=-inf;
		if(x==-6) b=1;
		else if(x==-9) a=1;
		else if(!c[x]) l1=l2=r1=r2=0;
	}
}t[maxn<<2];
void upd(int i){
	int lc=i<<1,rc=i<<1|1;
	if(t[lc].b>t[rc].a) t[i].a=t[lc].a,t[i].b=t[lc].b-t[rc].a+t[rc].b;
	else t[i].a=t[lc].a+t[rc].a-t[lc].b,t[i].b=t[rc].b;
	t[i].dis=max(max(t[lc].r1+t[rc].l2,t[lc].r2+t[rc].l1),max(t[lc].dis,t[rc].dis));
	t[i].l1=max(t[lc].l1,max(t[lc].a+t[lc].b+t[rc].l2,t[lc].a-t[lc].b+t[rc].l1));
	t[i].l2=max(t[lc].l2,t[lc].b-t[lc].a+t[rc].l2);
	t[i].r1=max(t[rc].r1,max(t[rc].a+t[rc].b+t[lc].r2,t[rc].b-t[rc].a+t[lc].r1));
	t[i].r2=max(t[rc].r2,t[rc].a-t[rc].b+t[lc].r2);
}
void build(int i,int l,int r){
	if(l==r) {t[i].init(s[l]);return;}
	int mid=(l+r)>>1;
	build(i<<1,l,mid),build(i<<1|1,mid+1,r);
	upd(i);
}
void insert(int i,int l,int r,int x){
	if(l==r) {t[i].init(s[l]);return;}
	int mid=(l+r)>>1;
	if(x<=mid) insert(i<<1,l,mid,x);
	else insert(i<<1|1,mid+1,r,x);
	upd(i);
}
int main()
{
	#ifndef ONLINE_JUDGE
		freopen("H.in","r",stdin);
	#endif
	int x,y,cnt;char op;
	read(n),cnt=n;
	for(int i=1;i<n;i++) read(x),read(y),line(x,y),line(y,x);
	dfs(1);
	build(1,1,sz);
	read(m);
	while(m--){
		while(!isalpha(op=getc()));
		if(op=='G') printf("%d\n",cnt>1?t[1].dis:cnt-1);
		else read(x),cnt+=c[x]?-1:1,c[x]=!c[x],insert(1,1,sz,pos[x]);
	}
}

猜你喜欢

转载自blog.csdn.net/C20181220_xiang_m_y/article/details/88863317