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;

}


posted @ 2015-03-10 17:28  New_Godess  阅读(368)  评论(0编辑  收藏  举报