膜拜了一下午某岛的东西,然后恍然大悟,原来还能这么做!
速度还是很快的2333
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
using namespace std;
const int maxn=100005;
const int head=-1,tail=-2,inf=674275764;
vector <int> e[maxn];
typedef vector <int>::iterator ii;
int seq[maxn*6],pos[maxn*2],color[maxn*2],vis[maxn*2],cnt;
int dark;
int n,m;
char op[6];
int tu,tv;
//-- tree
struct seg_tree{
int l,r,dist;
int r_p,r_m,l_p,l_m;
void set(int p)
{
l=(seq[p]==head);
r=(seq[p]==tail);
dist=-inf;
l_p=l_m=r_p=r_m=
(seq[p]>=0 && color[seq[p]]==0)?0:-inf;
}
}t[maxn*12];
void update(int x)
{
t[x].l=t[x*2+1].l+max(t[x*2].l-t[x*2+1].r,0);
t[x].r=t[x*2].r+max(t[x*2+1].r-t[x*2].l,0);
t[x].dist=max(max(t[x*2].dist,t[x*2+1].dist),max(t[x*2].r_p+t[x*2+1].l_m,t[x*2].r_m+t[x*2+1].l_p));
t[x].l_p=max(max(t[x*2+1].l_p+t[x*2].r-t[x*2].l,t[x*2+1].l_m+t[x*2].r+t[x*2].l),t[x*2].l_p);
t[x].l_m=max(t[x*2].l_m,t[x*2+1].l_m-t[x*2].r+t[x*2].l);
t[x].r_p=max(max(t[x*2].r_p-t[x*2+1].r+t[x*2+1].l,t[x*2].r_m+t[x*2+1].r+t[x*2+1].l),t[x*2+1].r_p);
t[x].r_m=max(t[x*2+1].r_m,t[x*2].r_m+t[x*2+1].r-t[x*2+1].l);
}
void build(int x,int l,int r)
{
if (l==r)
{
t[x].set(l);
return;
}
int mid=(l+r)/2;
build(x*2,l,mid);build(x*2+1,mid+1,r);
update(x);
}
void edit(int x,int l,int r,int p)
{
if (l==r)
{
t[x].set(l);
return;
}
int mid=(l+r)/2;
if (p<=mid)
edit(x*2,l,mid,p);
else
edit(x*2+1,mid+1,r,p);
update(x);
}
void dfs(int x)
{
vis[x]=true;
seq[++cnt]=head;
pos[x]=++cnt;
seq[cnt]=x;
for (ii j=e[x].begin();j!=e[x].end();j++)
if (!vis[*j])
dfs(*j);
seq[++cnt]=tail;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<n;i++)
{
scanf("%d%d",&tu,&tv);
e[tu].push_back(tv);
e[tv].push_back(tu);
}
dark=n;
dfs(1);
build(1,1,cnt);
scanf("%d",&m);
while (m--)
{
scanf("%s",op);
if (op[0]=='G')
{
if (dark==0)
printf("-1\n");
else if (dark==1)
printf("0\n");
else
printf("%d\n",t[1].dist);
}
else
{
scanf("%d\n",&tu);
color[tu]=1-color[tu];
dark+=(color[tu])?(-1):(1);
edit(1,1,cnt,pos[tu]);
}
}
return 0;
}