ZOJ 3686 A Simple Tree Problem

来源:互联网 发布:js隐藏img标签 编辑:程序博客网 时间:2024/06/06 03:41

这个题大一的时候做过,当时感觉好屌,题目这么简洁,但是暴力都不会写。

现在重写,其实算是个比较经典的做法了吧,利用dfs到的时间戳构建一个线段树,

然后就是不难想的基本操作改改了。


注意:懒惰标记不要搞错,如果对一个点有2个懒惰标记这个点懒惰标记取0.

/*    author:ray007great    version:1.0*/#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<queue>using namespace std;typedef long long ll;/*  define */#define sf(a) scanf("%d",&a)#define sfs(a) scanf("%s",a)#define sfI(a) scanf("%I64d",&a)#define pf(a) printf("%d\n",a)#define pfI(a) printf("%I64d\n",a)#define rep(i,a,b) for(int i=(a);i<=(b);i++)#define repd(i,a,b) for(int i=(a);i>=(b);i--)#define rep1(i,a,b) for(int i=(a);i<(b);i++)#define clr(a) memset(a,0,sizeof(a))#define pfk  printf("fuck\n")/*  define */const int N = 310000;int clock1;int lleft[N],rright[N];int val[4*N],lazy[4*N];vector<int> g[N];void dfs(int x){    if(lleft[x]) return ;    lleft[x]=++clock1;    int sz=g[x].size();    for(int i=0;i<sz;i++) dfs(g[x][i]);    rright[x]=clock1;}void Up(int o){    val[o]=val[o<<1]+val[o<<1|1];}void Cov(int l,int r,int o){    val[o]=(r-l+1)-val[o];lazy[o]=!lazy[o];}void release(int l,int r,int o){    int m=(l+r)>>1;    if(lazy[o]){        Cov(l,m,o<<1);Cov(m+1,r,o<<1|1);        lazy[o]=0;    }}int ql,qr;//query rangeint query(int l,int r,int o){    if(l>=ql && r<=qr)  return val[o];    release(l,r,o);    int m=(l+r)>>1,res=0;    if(ql<=m) res+=query(l,m,o<<1);    if(m<qr) res+=query(m+1,r,o<<1|1);    return res;}int ul,ur;//update rangevoid update(int l,int r,int o){    if(l>=ul && r<=ur){        Cov(l,r,o);return ;    }    release(l,r,o);    int m=(l+r)>>1;    if(ul<=m) update(l,m,o<<1);    if(m<ur) update(m+1,r,o<<1|1);    Up(o);}void build(int l,int r,int o){    clr(val);clr(lazy);}int main(){    int n,q,x;    while(~scanf("%d%d",&n,&q)){        clock1=0;        for(int i=1;i<=n;i++) g[i].clear();        clr(lleft);clr(rright);        for(int i=2;i<=n;i++){            scanf("%d",&x);            g[x].push_back(i);g[i].push_back(x);        }        dfs(1);build(1,n,1);        char op[10];        for(int i=1;i<=q;i++){            scanf("%s%d",op,&x);            if(op[0]=='q'){                ql=lleft[x];qr=rright[x];                printf("%d\n",query(1,n,1));            }            else if(op[0]=='o'){                ul=lleft[x];ur=rright[x];                update(1,n,1);            }        }        printf("\n");    }    return 0;}

原创粉丝点击