ZOJ 3686 A Simple Tree Problem (线段树)
2013-04-16 17:06
387 查看
题意类似于POJ3321,但是这里每次操作的时候更新了子树中的所有节点值,而且每次查询需要进行延迟标记,所以如果跟POJ3321一样用树状数组不适合,这里用线段树来写,开始先dfs一边用时间戳进行节点标记。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define MAX 100001 #define lson (rt<<1) #define rson (rt<<1|1) #define ll int int head[MAX],to[MAX<<1],next[MAX<<1],edge; int begin[MAX],end[MAX],ind,n,m; bool vis[MAX]; struct Node { int l,r; ll sum; int add; int len() { return r-l+1; } } tree[MAX<<2]; void init() { memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); edge=ind=0; } inline void add(int u,int v) { to[edge]=v,next[edge]=head[u],head[u]=edge++; to[edge]=u,next[edge]=head[v],head[v]=edge++; } inline void pushUp(int rt) { tree[rt].sum=tree[lson].sum+tree[rson].sum; } inline void pushDown(int rt) { int add=tree[rt].add%2; if(add) { tree[lson].add+=add; tree[lson].sum=tree[lson].len()-tree[lson].sum; tree[rson].add+=add; tree[rson].sum=tree[rson].len()-tree[rson].sum; tree[rt].add=0; } } void build(int rt,int l,int r) { tree[rt].l=l,tree[rt].r=r,tree[rt].add=0; if(l==r) { tree[rt].sum=0; return ; } int mid=(l+r)>>1; build(lson,l,mid); build(rson,mid+1,r); pushUp(rt); } void update(int rt,int l,int r) { if(l<=tree[rt].l&&r>=tree[rt].r) { tree[rt].add++; tree[rt].sum=tree[rt].len()-tree[rt].sum; return; } pushDown(rt); int mid=(tree[rt].l+tree[rt].r)>>1; if(l<=mid) update(lson,l,r); if(r>mid) update(rson,l,r); pushUp(rt); } ll query(int rt,int l,int r) { if(l<=tree[rt].l&&r>=tree[rt].r) { return tree[rt].sum; } pushDown(rt); int mid=(tree[rt].l+tree[rt].r)>>1; ll res=0; if(l<=mid) res+=query(lson,l,r); if(r>mid) res+=query(rson,l,r); return res; } void dfs(int now) { begin[now]=++ind; vis[now]=1; for(int i=head[now]; ~i; i=next[i]) if(!vis[to[i]]) dfs(to[i]); end[now]=ind; } int main() { int i,u,m; char ch[2]; while(~scanf("%d%d",&n,&m)) { init(); build(1,1,n); for(i=2; i<=n; ++i) { scanf("%d",&u); add(u,i); } dfs(1); while(m--) { scanf("%s",ch); if(ch[0]=='q') { scanf("%d",&u); printf("%d\n",query(1,begin[u],end[u])); } else { scanf("%d",&u); update(1,begin[u],end[u]); } } printf("\n"); } return 0; }
相关文章推荐
- ZOJ 3686 A Simple Tree Problem(线段树)
- ZOJ 3686 A Simple Tree Problem(线段树)
- zoj 3686 A Simple Tree Problem(dfs+线段树)
- zoj 3686 A Simple Tree Problem (线段树)
- ZOJ 3686 A Simple Tree Problem(线段树)
- ZOJ 3686 A Simple Tree Problem (线段树)
- ZOJ-3686 A Simple Tree Problem 线段树
- ZOJ 3686 A Simple Tree Problem(树转线段树+线段树区间更新)
- ZOJ 3686 A Simple Tree Problem(将对树的操作转化成区间=>线段树)
- zoj 3686 A Simple Tree Problem (经典,利用dfs序维护树)
- zoj 3686 A Simple Tree Problem
- ZOJ_3686_A Simple Tree Problem(线段树成端更新)
- ZOJ 3686 A Simple Tree Problem
- zoj3686 A Simple Tree Problem
- zoj 3686 A Simple Tree Problem
- ZOJ 3686 A A Simple Tree Problem
- ZOJ 3686 A Simple Tree Problem
- ZOJ3686 A Simple Tree Problem
- ZOJ 3686 A Simple Tree Problem
- ZOJ 3686 : A Simple Tree Problem