BZOJ 1095: [ZJOI2007]Hide 捉迷藏(线段树维护括号序列)
这个嘛= =链剖貌似可行,不过好像代码长度很长,懒得打(其实是自己太弱了QAQ)百度了一下才知道有一种高大上的叫括号序列的东西= =
岛娘真是太厉害了,先丢链接:http://www.shuizilong.com/house/archives/bzoj-1095-zjoi2007hide-%E6%8D%89%E8%BF%B7%E8%97%8F/
这个括号序列貌似可以解决一些关于树上两点距离查询的问题(可以替代点分治?)好像很高端的样子找论文看看吧
CODE:(最近在搞github,相信不久就能够直接贴链接跑了~~~)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 301000
vector<int> e[maxn];
int list[maxn],id[maxn],cnt;
int dfs(int x,int fa) {
list[++cnt]=1;
list[id[x]=++cnt]=0;
for (int i=0;i<e[x].size();i++) {
if (e[x][i]==fa) continue;
dfs(e[x][i],x);
}
list[++cnt]=-1;
return 0;
}
#define maxint 0x7fffffff
#define inf (maxint>>2)
struct bo{
int a,b,ans,lp,lm,rp,rm;
void init(){a=b=0;ans=lp=lm=rp=rm=-inf;}
void set(bool flag) {
if (flag) {
ans=lp=lm=rp=rm=-inf;
}else {
ans=lp=lm=rp=rm=0;
}
}
};
bo update(bo l,bo r) {
bo ans;
ans.ans=max(l.ans,r.ans);
ans.ans=max(l.rp+r.lm,ans.ans);
ans.ans=max(r.lp+l.rm,ans.ans);
if (l.b>r.a) {ans.a=l.a;ans.b=r.b+l.b-r.a;}
else {ans.a=l.a+r.a-l.b;ans.b=r.b;}
ans.rp=max(max(r.rp,l.rp-r.a+r.b),l.rm+r.a+r.b);
ans.rm=max(r.rm,l.rm+r.a-r.b);
ans.lp=max(max(l.lp,r.lp+l.a-l.b),r.lm+l.a+l.b);
ans.lm=max(l.lm,r.lm+l.b-l.a);
return ans;
}
struct node{
int l,r;bo b;
}t[maxn*8];
#define lc (x<<1)
#define rc (lc^1)
#define mid ((l+r)>>1)
int build(int x,int l,int r) {
t[x].l=l,t[x].r=r;
if (l==r) {
t[x].b.init();
if (list[l]==1) t[x].b.b=1;
if (list[l]==-1) t[x].b.a=1;
if (list[l]==0) t[x].b.set(0);
return 0;
}
build(lc,l,mid);build(rc,mid+1,r);
t[x].b=update(t[lc].b,t[rc].b);
return 0;
}
int set(int x,int y,bool flag) {
int l=t[x].l,r=t[x].r;
if (l>y||r<y) return 0;
if (l==r) {
t[x].b.set(flag);
return 0;
}
set(lc,y,flag);set(rc,y,flag);
t[x].b=update(t[lc].b,t[rc].b);
}
bool b[maxn];
#define pb push_back
int main(){
int n;
// freopen("1.in","r",stdin);
scanf("%d",&n);
for (int i=1;i<n;i++) {
int x,y;
scanf("%d%d",&x,&y);
e[x].pb(y);e[y].pb(x);
}
dfs(1,0);
build(1,1,n*3);
int T,cnt=n;
scanf("%d",&T);
// for (int i=1;i<=n*3*4;i++) printf("%d %d %d %d %d\n",i,t[i].l,t[i].r,t[i].b.a,t[i].b.b);
while (T--) {
char opt[2];int x;
scanf("%s",opt);
switch (opt[0]) {
case 'G' :
if (cnt==0) printf("-1\n");
else if (cnt==1) printf("0\n");
else printf("%d\n",t[1].b.ans);
break;
case 'C' :
scanf("%d",&x);
set(1,id[x],(b[x]^=1));
cnt+=b[x]?-1:1;
break;
}
}
return 0;
}