【POJ3321】Apple Tree 苹果树 线段树
2017-03-19 18:51
489 查看
题目描述
有一棵N个结点的树,一开始每个结点上都有一个苹果,每次有两种操作:(1)C x:如果x结点上有一个苹果,那么摘下它,否则x节点上会再生出一个苹果;
(2)Q x:询问以x结点为根的子树中苹果的个数;
你要对于每个Q操作,输出对应的答案。
题目大意
树上改变一个节点的权值,询问以一个点的子树的权值和。数据范围
n,q<=10^5样例输入
31 2
1 3
3
Q 1
C 2
Q 1
样例输出
32
解题思路
首先求出dfs序,则可以将树上的操作改为序列上的操作,记f[x][0]为x第一次出现的位置,f[x][1]为x第二次出现的位置。故答案就是∑i=f[x][0]f[x][1]vl[i]2也就成为了普通的线段树(树状数组)的题目了。代码
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #define Maxn 100005 using namespace std; inline int Getint(){int x=0,f=1;char ch=getchar();while('0'>ch||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;} inline char Getch(){ char ch=getchar(); while(ch!='C'&&ch!='Q')ch=getchar(); return ch; } int f[Maxn][2],h[Maxn],cnt=0; bool w[Maxn]; struct node{int to,next;}e[Maxn*2]; void AddEdge(int x,int y){ c786 e[++cnt]=(node){y,h[x]};h[x]=cnt;} void dfs(int x,int L){ f[x][0]=++cnt; for(int p=h[x];p;p=e[p].next){ int y=e[p].to; if(y==L)continue; dfs(y,x); } f[x][1]=++cnt; } struct NODE{ int L,r,Sum; }Tree[Maxn*4*2]; void PushUp(int v){ Tree[v].Sum=Tree[2*v].Sum+Tree[2*v+1].Sum; } void Build(int v,int L,int r){ Tree[v]=(NODE){L,r,L==r}; if(L==r)return; Build(v*2,L,(L+r)/2); Build(v*2+1,(L+r)/2+1,r); PushUp(v); } int Ask(int v,int L,int r){ if(r<Tree[v].L||Tree[v].r<L)return 0; if(L<=Tree[v].L&&Tree[v].r<=r)return Tree[v].Sum; return Ask(2*v,L,r)+Ask(2*v+1,L,r); } void Modify(int v,int pos,int vl){ if(!v)return; if(pos<Tree[v].L||Tree[v].r<pos)return; if(Tree[v].L==Tree[v].r){ Tree[v].Sum+=vl; return; } Modify(2*v,pos,vl); Modify(2*v+1,pos,vl); PushUp(v); } int main(){ memset(w,1,sizeof(w)); int n=Getint(); for(int i=1;i<n;i++){ int x=Getint(),y=Getint(); AddEdge(x,y); AddEdge(y,x); } cnt=0; dfs(1,0); Build(1,0,n*2+2); int q=Getint(); while(q--){ char ch=Getch(); if(ch=='Q'){ int x=Getint(); cout<<(Ask(1,f[x][0],f[x][1]))/2<<"\n"; }else{ int x=Getint(); if(w[x])Modify(1,f[x][0],-1),Modify(1,f[x][1],-1),w[x]^=1; else Modify(1,f[x][0],1),Modify(1,f[x][1],1),w[x]^=1; } } return 0; }
相关文章推荐
- [POJ3321] Apple Tree 苹果树 - 树状数组
- ACM学习历程——POJ3321 Apple Tree(搜索,线段树)
- 线段树 poj3321 Apple Tree
- POJ 题目3321 Apple Tree(线段树)
- codevs1228 苹果树(dfs序&&(线段树||树状数组))
- POJ3321 Apple Tree(DFS序 + 树状数组)
- POJ3321 - Apple Tree
- POJ3321-Apple Tree(dfs序+线段树)
- POJ 3321 Apple Tree 线段树
- POJ3321 Apple Tree
- poj3321 Apple Tree(DFS+树状数组)
- [POJ3321]Apple Tree
- POJ3321 Apple Tree
- poj 3321 Apple Tree(线段树)
- 【poj3321】Apple Tree——树状数组&DFS
- 【POJ 3321】【dfs序(讲解)+(树状数组或者线段树)】Apple Tree【给你一颗树,最初每个节点上都有一个苹果,有两种操作单点修改和查询子树的苹果个数】
- poj3321 Apple Tree
- POJ3321 Apple Tree(DFS序)
- POJ3321 Apple Tree (树状数组)
- POJ3321:Apple Tree