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

时间:2021-07-24 12:56:36

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

#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;
}