【BZOJ 1095】 [ZJOI2007]Hide 捉迷藏 括号序列

太神了!!!!
这种方法看来不适合我这种蒟蒻!!
下午还是老老实实用分治把!!

#include <cstdio>
#include <iostream>
#include <algorithm>
#define INF 1000000000
using namespace std;
struct H
{
	int ans;
	int C2,C5;
	int L25,R25;
	int L5,R2;
}seg_num[1000000*4+1];
int init[1000000+1];
int n,m;
int tot,g[1000000+1],num[1000000+1],nnext[1000000+1];

int pos[1000000+1];
bool is_black[1000000+1];
int v[1000000*3+1],cnt;

void Add(int x,int y)
{
	tot++;
	nnext[tot]=g[x];
	g[x]=tot;
	num[tot]=y;
}

void dfs (int x)
{
	v[++cnt]=-5;
	v[++cnt]=x;pos[x]=cnt;
	for(int i=g[x];i;i=nnext[i])
		if(!is_black[num[i]])
			is_black[num[i]]=true,dfs(num[i]);
	v[++cnt]=-2;
}
void Up(int now)
{
	int L=now*2,R=now*2+1;
	if(seg_num[L].C5>seg_num[R].C2)
	{
		seg_num[now].C2=seg_num[L].C2;
		seg_num[now].C5=seg_num[L].C5-seg_num[R].C2+seg_num[R].C5;
	}
	else
	{
		seg_num[now].C2=seg_num[L].C2+seg_num[R].C2-seg_num[L].C5;
		seg_num[now].C5=seg_num[R].C5;
	}
	seg_num[now].ans=max(max(seg_num[L].ans,seg_num[R].ans),max(seg_num[L].R25+seg_num[R].L5,seg_num[R].L25+seg_num[L].R2));
	seg_num[now].L25=max(seg_num[L].L25,max(seg_num[L].C5+seg_num[L].C2+seg_num[R].L5,seg_num[L].C2-seg_num[L].C5+seg_num[R].L25));
	seg_num[now].R25=max(seg_num[R].R25,max(seg_num[L].R2+seg_num[R].C2+seg_num[R].C5,seg_num[L].R25+seg_num[R].C5-seg_num[R].C2));
	seg_num[now].L5=max(seg_num[L].L5,seg_num[R].L5+seg_num[L].C5-seg_num[L].C2);
	seg_num[now].R2=max(seg_num[R].R2,seg_num[L].R2+seg_num[R].C2-seg_num[R].C5);
}
void Build(int now,int L,int R)
{
	if(L==R)
	{
		if(v[L]<0)
		{
			seg_num[now].L25=seg_num[now].R25=seg_num[now].R2=seg_num[now].L5=-INF;
			if(v[L]==-2)
				seg_num[now].C2=1;
			else
				seg_num[now].C5=1;
		}
		
		return ;
	}
	int mid=(L+R)/2;
	Build(now*2,L,mid);
	Build(now*2+1,mid+1,R);
	Up(now);
}
void Change(int now,int L,int R,int loc)
{
	if(L==R)
	{
		if(is_black[v[L]]==1)
			seg_num[now]=(H){0,0,0,0,0,0,0};
		else
			seg_num[now]=(H){0,0,0,-INF,-INF,-INF,-INF};
		return ;
	}
	int mid=(L+R)/2;
	if(loc<=mid)
	Change(now*2,L,mid,loc);
	else
	Change(now*2+1,mid+1,R,loc);
	Up(now);
}
int main()
{
	cin>>n;
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d %d",&x,&y);
		Add(x,y);
		Add(y,x);
	}
	is_black[1]=true;
	dfs(1);
	n*=3;
	Build(1,1,n); 
	cin>>m; 
	char c;int x;
	int nn=n/3;
	while(m--)
	{
		getchar();
		c=getchar();
		if(c=='G')
		{
			if(nn==0) printf("-1\n");
			else if(nn==1) printf("0\n");
			else printf("%d\n",seg_num[1].ans);
		}
		else
		{
			scanf("%d",&x);
			if(is_black[x]==true)
				nn--;
			else nn++;
			is_black[x]=!is_black[x];
			Change(1,1,n,pos[x]);
		}
	}
	return 0;
}
posted @ 2016-01-18 11:17  sxb_201  阅读(377)  评论(0编辑  收藏  举报