[codeforces] 877E. Danil and a Part-time Job(DFS序+线段树)
来源:互联网 发布:淘宝怎么进行实名认证 编辑:程序博客网 时间:2024/05/21 19:23
[codeforces] 877E. Danil and a Part-time Job(DFS序+线段树)
题目链接: E. Danil and a Part-time Job
题目大意:
给一棵大小为n的以1为根节点的树。 每个点的值为0或1, 有q个操作:
1. pow v, 对于v以及v的子树所有节点01反转。
2. get v, 查询v以及v的子树中1节点的个数。
数据范围:
解题思路:
dfs序+线段树, 线段树用来维护每个点被反转了几次, 通过这道题让我又深一步的理解了线段树下放的思想: 当你查询到一个点的时候, 这个点肯定已经是被操作过的。所以反转应该写在下放的时候。
AC代码:
/******************************************** *Author* :ZZZZone *Created Time* : 五 11/ 3 20:03:46 2017 * Ended Time* : 六 11/ 4 00:05:58 2017*********************************************/#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>#include <stack>using namespace std;typedef pair<int, int> PII;typedef long long LL;typedef unsigned long long ULL;const int MaxN = 2e5;vector<int> edge[MaxN + 5];int head[MaxN + 5], tail[MaxN + 5], re[MaxN + 5];int n, q, tot, now;int a[MaxN + 5];int sum1[4 * MaxN + 5], sum0[4 * MaxN + 5], add[4 * MaxN + 5];void dfs(int u, int fa){ head[u] = ++tot; re[tot] = u; for(int i = 0; i < edge[u].size(); i++){ int v = edge[u][i]; if(v != fa) dfs(v, u); } tail[u] = tot;}void pushup(int rt){ sum1[rt] = sum1[rt << 1] + sum1[rt << 1 | 1]; sum0[rt] = sum0[rt << 1] + sum0[rt << 1 | 1];}void build(int l, int r, int rt){ if(l == r){ now++; if(a[re[now]] == 1) sum1[rt]++; else sum0[rt]++; return; } int mid = (l + r) >> 1; build(l, mid, rt << 1); build(mid + 1, r, rt << 1 | 1); pushup(rt);}void pushdown(int rt){ if(add[rt]){ add[rt << 1] ^= 1; add[rt << 1 | 1] ^= 1; swap(sum1[rt << 1], sum0[rt << 1]); swap(sum1[rt << 1 | 1], sum0[rt << 1 | 1]); add[rt] = 0; }}void update(int L, int R, int l, int r, int rt){ if(L <= l && R >= r){ swap(sum0[rt], sum1[rt]); add[rt] ^= 1; return; } pushdown(rt); int mid = (l + r) >> 1; if(L <= mid) update(L, R, l, mid, rt << 1); if(R > mid) update(L, R, mid + 1, r, rt << 1 | 1); pushup(rt);}int query(int L, int R, int l, int r, int rt){ if(L <= l && R >= r){ //printf("%d %d %d ", sum0[rt], sum1[rt], add[rt]); return sum1[rt]; } pushdown(rt); int mid = (r + l) >> 1; LL ret = 0; if(L <= mid) ret += query(L, R, l, mid, rt << 1); if(R > mid) ret += query(L, R, mid + 1, r, rt << 1 | 1); return ret;}int main(){ scanf("%d", &n); for(int i = 2; i <= n; i++){ int u; scanf("%d", &u); edge[u].push_back(i); } for(int i = 1; i <= n; i++) scanf("%d", &a[i]); dfs(1, 0); scanf("%d", &q); build(1, n, 1); while(q--){ char tmp[5]; int p; scanf("%s %d\n", tmp, &p); if(tmp[0] == 'p') update(head[p], tail[p], 1, n, 1); else if(tmp[0] == 'g') printf("%d\n", query(head[p], tail[p], 1, n, 1)); } return 0;}
阅读全文
0 0
- Codeforces 877E Danil and a Part-time Job【Dfs序+线段树】
- Codeforces 877 E Danil and a Part-time Job(线段树+dfs序)
- [codeforces] 877E. Danil and a Part-time Job(DFS序+线段树)
- CodeForces 877E Danil and a Part-time Job (dfs序+线段树)
- Codeforces-877E:Danil and a Part-time Job(DFS序列+线段树)
- codeforces 877E. Danil and a Part-time Job (DFS序列+线段树)
- Codeforces Round #442 (Div. 2) E. Danil and a Part-time Job【线段树+dfs序】
- Codeforces Round #442 (Div. 2) 877 E. Danil and a Part-time Job DFS序 线段树
- codeforces 877 problem E Danil and a Part-time Job 【dfs序 + 线段树区间异或修改】
- CF#877 E. Danil and a Part-time Job(DFS序+线段树)
- Codeforces Round #442 (Div. 2)-E-Danil and a Part-time Job(DFS序+线段树区间更新)
- Codeforces Round #442 (Div. 2) E. Danil and a Part-time Job DFS序+树链剖分+线段树区间^
- Codeforces Round #442 (Div. 2) E. Danil and a Part-time Job (dfs序+线段树)
- Codeforces Round #442E-dfs序&线段树的区间更新区间查询-Danil and a Part-time Job
- [CodeForces877 E. Danil and a Part-time Job]dfs序+线段树
- Danil and a Part-time Job codeforces dfs序,线段树
- Codeforces 877E Danil and a Part-time Job
- Codeforces Round #442 (Div. 2) Danil and a Part-time Job dfs序+线段树区间反转
- 单链表基本操作的C语言实现(链式存储结构)
- dict
- java对象的内存
- Python 编码规范
- Javascript——简介
- [codeforces] 877E. Danil and a Part-time Job(DFS序+线段树)
- setInterval图片缓冲(js)
- 数据结构--线性表C实现
- 试试写个博客
- 升级nodejs, npm到某一版本
- php实现兼容Unicode文字的字符串大小写转换strtolower()和strtoupper()
- history.go(-1)、history.back()区别
- 实验6:图的实验1
- springmvc自定义参数绑定实现日期参数绑定