ZOJ_3686_A Simple Tree Problem(线段树成端更新)
来源:互联网 发布:淘宝pc端是在哪里 编辑:程序博客网 时间:2024/05/23 01:56
题型:数据结构
题意:
给一棵树,初始每个节点的值为0,给出m个操作:
(1)o Node:将以节点Node为根的子树的所有节点的值取反。
(2)q Node:查询以节点Node为根的子树中1的节点的个数。
分析:
按照中序遍历,给每个节点标上id,这样,可以很快的求出某个点作为根节点所构成的子树所包括的范围,即子树的最右下节点。
这样就可以构造出线段树了,每个节点存着对应管辖范围内1的个数,当然,由于需要进行成段更新,每个节点需要设置一个延迟标记。
对于将子树中所有的节点取反,就是用子树的节点数减去当前的1的个数。
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#define mt(a,b) memset(a,b,sizeof(a))#define lrrt int L,int R,int rt#define iall 1,n,1#define imid int mid=(L+R)>>1;#define lson L,mid,rt<<1#define rson mid+1,R,rt<<1|1using namespace std;const int M = 123456;struct T{ int val,lazy;}tree[M<<2];void pushup(int rt){ tree[rt].val = tree[rt<<1].val + tree[rt<<1|1].val;}void pushdown(int mid,lrrt){ if(tree[rt].lazy){ tree[rt<<1].val = mid - L + 1 - tree[rt<<1].val; tree[rt<<1].lazy ^= 1; tree[rt<<1|1].val = R - mid - tree[rt<<1|1].val; tree[rt<<1|1].lazy ^= 1; tree[rt].lazy = 0; }}void update(int x,int y,lrrt){ if(x<=L && R<=y){ tree[rt].val = R - L + 1 - tree[rt].val; tree[rt].lazy ^= 1; return; } imid; pushdown(mid,L,R,rt); if(mid >= x) update(x,y,lson); if(mid < y) update(x,y,rson); pushup(rt);}int query(int x,int y,lrrt){ if(x<=L && R <=y){ return tree[rt].val; } imid; pushdown(mid,L,R,rt); int ans = 0; if(mid >= x) ans += query(x,y,lson); if(mid < y) ans += query(x,y,rson); return ans;}struct E{ int u,v,next;}e[M];int le,head[M];void init(){ le = 0; mt(head,-1);}void add(int u,int v){ e[le].u = u; e[le].v = v; e[le].next = head[u]; head[u] = le++;}struct G{ int l,r;}node[M];int Index;void dfs(int u){ node[u].l = ++Index; for(int i=head[u];~i;i=e[i].next){ dfs(e[i].v); } node[u].r = Index;}int main() { int n,m,x; while(~scanf("%d%d",&n,&m)){ init(); for(int i=2;i<=n;i++){ scanf("%d",&x); add(x,i); } Index = 0; dfs(1); mt(tree,0); char op[5]; while(m--){ scanf("%s%d",op,&x); if(op[0] == 'o'){ update(node[x].l,node[x].r,iall); } else{ printf("%d\n",query(node[x].l,node[x].r,iall)); } } puts(""); } return 0;}
0 0
- ZOJ_3686_A Simple Tree Problem(线段树成端更新)
- ZOJ 3686 A Simple Tree Problem(树转线段树+线段树区间更新)
- BNU A Simple Tree Problem 线段树
- ZOJ3696-A Simple Tree Problem 线段树
- BNUOJ 28887 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 (DFS+线段树)
- ZOJ 3686 A Simple Tree Problem(线段树)
- poj 3468 A Simple Problem with Integers(线段树成段更新)
- poj3468A Simple Problem with Integers(线段树成段更新)
- POJ3468A Simple Problem with Integers(线段树成段更新--Lazy标记)
- 线段树成段更新----A Simple Problem with Integers
- A Simple Problem with Integers +poj+线段树区间更新
- POJ3468_A Simple Problem with Integers(线段树/成段更新)
- poj3468 A Simple Problem with Integers 线段树区间更新
- HDU4973A simple simulation problem.(线段树,区间更新)
- 【iOS】网络加载图片缓存与SDWebImage
- 大矮子灰 烧纸灰 商会 用酒
- 指定浏览某浏览器
- VMware Workstation环境下安装增强工具
- hdu 不容易系列之(3)―― LELE的RPG难题
- ZOJ_3686_A Simple Tree Problem(线段树成端更新)
- [leetcode] Word Break
- cas入门之二十:cas审计日志Inspektr(下)
- java Fork-join框架
- iOS开发之Objective-C与JavaScript的交互
- 搜索题集
- 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛 (Floyd)
- 光盘启动 (Boot from CDROM) Part 1- SakiProject
- Eddy's digital Roots