ZOJ 3686 A Simple Tree Problem
这个题大一的时候做过,当时感觉好易做图,题目这么简洁,但是暴力都不会写。现在重写,其实算是个比较经典的做法了吧,利用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("易做图\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 range int 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 range void 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; }
补充:软件开发 , C++ ,