Codeforces Round #442 (Div. 2) E. Danil and a Part-time Job (dfs序树型转线性 线段树区间修改区间查询)
来源:互联网 发布:金华火腿 知乎 编辑:程序博客网 时间:2024/05/22 04:40
#include <bits/stdc++.h>using namespace std;#define maxn 200005int c[maxn * 4], lazy[maxn * 4], lft[maxn], rght[maxn], tot, sz[maxn];vector<vector<int> > g(maxn);void pushdown(int o, int l, int r){if(l == r || lazy[o] == 0) return;int mid = l + r >> 1;c[o << 1] = mid - l + 1 - c[o << 1];c[o << 1 | 1] = r - mid - c[o << 1 | 1];lazy[o << 1] ^= 1;lazy[o << 1 | 1] ^= 1;lazy[o] = 0;}void add(int o, int l, int r, int L, int R){pushdown(o, l, r);if(l >= L && r <= R){c[o] = r - l + 1 - c[o];lazy[o] ^= 1;return ;}int mid = l + r >> 1;if(mid >= L) add(o << 1, l, mid, L, R);if(mid < R) add(o << 1 | 1, mid + 1, r, L, R);c[o] = c[o << 1] + c[o << 1 | 1];}void dfs(int x){lft[x] = tot;for(int i = 0; i < g[x].size(); ++i){tot++;dfs(g[x][i]);}rght[x] = tot;}int getsum(int o, int l, int r, int L, int R){pushdown(o, l, r);if(l >= L && r <= R){return c[o];}int mid = l + r >> 1;int ans = 0;if(mid >= L) ans += getsum(o << 1, l, mid, L, R);if(mid < R) ans += getsum(o << 1 | 1, mid + 1, r, L, R);return ans;}int main(){int n, q, u;cin>>n;for(int i = 2; i <= n; ++i){scanf("%d", &u);g[u].push_back(i);}memset(c, 0, sizeof(c));memset(lazy, 0, sizeof(lazy));for(int i = 1; i <= n; ++i){scanf("%d", &sz[i]);}tot = 1;dfs(1);for(int i = 1; i <= n; ++i){if(sz[i]) add(1, 1, n, lft[i], lft[i]);}char s[5];scanf("%d", &q);while(q--){scanf("%s", s);if(s[0] == 'p'){scanf("%d", &u);add(1, 1, n, lft[u], rght[u]);sz[u] ^= 1;}else{scanf("%d", &u);printf("%d\n", getsum(1, 1, n, lft[u], rght[u]));}}}/*题意:一棵树,2e5个节点,每个节点上一个灯泡,2e5次操作,每次操作要么将以某个节点为子树上的所有灯泡全部翻转(开变关,关变开),要么询问以某个节点为子树上有多少个灯泡是亮的。思路:裸的dfs树形转线性+线段树区间修改和查询。。。。这题搞个dfs序就行了,维护一下子树上最小编号和最大编号,然后对应到线性区间上。区间修改和查询应该是线段树的基本操作了,用lazy记下翻转标记,*/
阅读全文
0 0
- 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
- Codeforces Round #442 (Div. 2) 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) 877 E. Danil and a Part-time Job DFS序 线段树
- codeforces 877 problem E Danil and a Part-time Job 【dfs序 + 线段树区间异或修改】
- Codeforces-877E:Danil and a Part-time Job(DFS序列+线段树)
- Codeforces 877 E Danil and a Part-time Job(线段树+dfs序)
- Codeforces Round #442 (Div. 2) E. Danil and a Part-time Job
- 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 #877 (Div. 2) E. Danil and a Part-time Job
- CF#877 E. Danil and a Part-time Job(DFS序+线段树)
- JDK7中BlockingQueue和Queue源码概述
- vim快捷键图解
- 图片裁剪,左右超出了等距裁剪图片左右部分 上下超出了就等距裁剪图片上下部分
- linux处理大量连接状态
- 数据库 图片展示Java代码
- Codeforces Round #442 (Div. 2) E. Danil and a Part-time Job (dfs序树型转线性 线段树区间修改区间查询)
- JSON与GO
- request的一些方法
- Oracle数据库SID显示异常处理
- C语言itoa()函数和atoi()函数详解(整数转字符C实现)
- JS脚本解析与执行顺序
- 利用DBMS_SPACE包对Oracle 表碎片进行监控与清理
- 神经网络 II:神经元模型
- 短科幻连载之《数据将来时》0