zoj3686(重新编号的线段树)
来源:互联网 发布:百旺金赋税控软件 编辑:程序博客网 时间:2024/05/22 17:40
题意:一颗n个节点的树,每个点都有一个权值(0或者1),初始化为0,两个操作:1、取反以i为节点的子树的所有点的权值;2、求以i点为根的子树中1的个数。
思路:dfs将所有节点重新编号,然后就是普通的成段更新。
代码如下:
#include<iostream>#include<algorithm>#include<cstring>#include<string>#include<stdio.h>#include<math.h>#include<vector>#define N 100005#define inf 0x7ffffff#define eps 1e-9#define pi acos(-1.0)using namespace std;vector<int> G[N];int hash[N],num[N];int id;void dfs(int cur){ num[cur] = 1; hash[cur] = id++; int len = G[cur].size(); for(int i = 0; i < len; i++) { dfs(G[cur][i]); num[cur] += num[ G[cur][i] ]; }}struct node{ int l,r,flag,sum;}tree[4*N];void build(int o,int l,int r){ tree[o].l = l; tree[o].r = r; tree[o].flag = tree[o].sum = 0; if(l == r) return; int m = (l+r)/2; build(2*o,l,m); build(2*o+1,m+1,r);}void pushup(int o){ tree[o].sum = tree[2*o].sum + tree[2*o+1].sum;}void pushdown(int o){ if(tree[o].flag) { tree[2*o].flag ^= 1; tree[2*o].sum = tree[2*o].r - tree[2*o].l + 1 - tree[2*o].sum; tree[2*o+1].flag ^= 1; tree[2*o+1].sum = tree[2*o+1].r - tree[2*o+1].l + 1 - tree[2*o+1].sum; tree[o].flag = 0; }}void update(int o,int x,int y){ if(x <= tree[o].l && tree[o].r <= y) { tree[o].sum = tree[o].r - tree[o].l + 1 - tree[o].sum; tree[o].flag ^= 1; return; } pushdown(o); int m = (tree[o].l+tree[o].r)/2; if(x <= m) update(2*o,x,y); if(y > m) update(2*o+1,x,y); pushup(o);}int query(int o,int x,int y){ if(x <= tree[o].l && tree[o].r <= y) return tree[o].sum; pushdown(o); int m = (tree[o].l+tree[o].r)/2; int ans = 0; if(x <= m) ans += query(2*o,x,y); if(y > m) ans += query(2*o+1,x,y); // pushup(o); return ans;}int main(){//freopen("input.txt","r",stdin);//freopen("output.txt","w",stdout); int n,m; while(scanf("%d%d",&n,&m) != EOF) { int i; for(i = 1; i <= n; i++) G[i].clear(); for(i = 2; i <= n; i++) { int x; scanf("%d",&x); G[x].push_back(i);//xµÄ¶ù×Ó½Úµã } id = 1; dfs(1); build(1,1,n); while(m--) { char s[10]; int x; scanf("%s%d",s,&x); if(s[0] == 'o') update(1,hash[x],hash[x]+num[x]-1); else printf("%d\n",query(1,hash[x],hash[x]+num[x]-1)); } printf("\n"); } return 0;}
0 0
- zoj3686(重新编号的线段树)
- zoj3686
- [DFS序列+线段树维护区间标记]ZOJ3686 A Simple Tree Problem
- SQLServer自动编号列的重新编号
- hdu3974 线段树 编号的处理 dfs 加 lazy思想
- WORD自动编号的图表标签重新编号
- 重新计算自动编号
- 重新计算自动编号
- Word 题注 重新编号
- Latex表格重新编号
- SQL Server 如何重新恢复自动编号列的序号
- SQL Server 如何重新恢复自动编号列的序号
- SQL Server 如何重新恢复自动编号列的序号
- SQL Server 如何重新恢复自动编号列的序号
- SQL Server 如何重新恢复自动编号列的序号
- Word中自定义的自动编号在重新编号时缩进问题的解决
- ACCESS数据库重新编号自动编号字段
- 二叉树的编号
- homework之数组
- 细说canvas使用
- 软件架构设计三步曲
- 谱聚类算法(Spectral Clustering)
- STM32与PID算法
- zoj3686(重新编号的线段树)
- 麻省理工学院公开课:算法导论1
- 树莓派学习笔记——apt方式安装opencv
- LeetCode Solutions : Rotate List
- Android Zip解压的问题
- GitHub 优秀的 Android 开源项目(值得研究)
- 设计模式-工厂模式
- cocos2dx 2.0-3.0 过渡篇
- 字符和字符串的输入输出(经典)