题目地址
题意:给你一棵树,1为根节点,每个节点都有应该状态0或者1,你有两种操作,pow的操作是把该节点以及他的所有子树的每个节点进行自身异或的操作,get就是查询该节点以及他的所有子树的每个节点有多少个1。
思路:我们先通过dfs一边把所有的子树搜索出来,并标记好,然后我们通过这个给出的子树的范围对线段树进行更新,之后的操作就是根据之前求出的子树范围来更新和查询,线段树就是一个简单的区间更新+延迟更新。

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <cstdio>
#include <algorithm>
#define N 200010
#define LL __int64
#define inf 0x3f3f3f3f
#define lson l,mid,ans<<1
#define rson mid+1,r,ans<<1|1
#define getMid (l+r)>>1
#define movel ans<<1
#define mover ans<<1|1
using namespace std;
const LL mod = 1e9 + 7;
const double eps = 1e-9;
struct node {LL sum;int lazy;int l, r;
}sum[N << 2];//线段树主体
int num[N], pos[N], len[N], pre[N], cnt;
vector<int> v[N];
struct Segment__Tree {int x, y;void pushUp(int ans) {sum[ans].sum = sum[movel].sum + sum[mover].sum;}void pushDown(int ans) {if (sum[ans].lazy) {sum[movel].lazy ^= 1;sum[mover].lazy ^= 1;sum[movel].sum = sum[movel].r - sum[movel].l + 1 - sum[movel].sum;sum[mover].sum = sum[mover].r - sum[mover].l + 1 - sum[mover].sum;sum[ans].lazy = 0;}}void build(int l, int r, int ans) {sum[ans].l = l;sum[ans].r = r;sum[ans].lazy = 0;if (l == r) {sum[ans].sum = num[pre[l]];return;}int mid = getMid;build(lson);build(rson);pushUp(ans);}LL solve(int l, int r, int ans) {if (l >= x&&r <= y) {return sum[ans].sum;}pushDown(ans);int mid = getMid;if (mid<x) {return solve(rson);}else if (mid >= y) {return solve(lson);}else {return solve(lson) + solve(rson);}}void updata(int l, int r, int ans) {if (l >= x&&r <= y) {sum[ans].sum = r - l + 1 - sum[ans].sum;sum[ans].lazy ^= 1;return;}pushDown(ans);int mid = getMid;if (mid<x) {updata(rson);}else if (mid >= y) {updata(lson);}else {updata(lson);updata(rson);}pushUp(ans);}
}tree;
void init(int n) {for (int i = 0; i <= n; i++) {v[i].clear();}
}
void dfs(int u) {int lens = v[u].size();for (int i = 0; i < lens; i++) {int vv = v[u][i];pos[vv] = ++cnt;//子树的起点pre[cnt] = vv;dfs(vv);len[vv] = cnt;//子树的终点}
}
int main() {cin.sync_with_stdio(false);int n, x, q;string str;while (cin >> n) {init(n);for (int i = 2; i <= n; i++) {cin >> x;v[x].push_back(i);}for (int i = 1; i <= n; i++) {cin >> num[i];}cin >> q;cnt = 0;pos[1] = ++cnt;pre[cnt] = 1;len[1] = n;dfs(1);tree.build(1, n, 1);while (q--) {cin >> str;if (str[0] == 'g') {cin >> x;tree.x = pos[x];tree.y = len[x];cout << tree.solve(1, n, 1) << endl;}else {cin >> x;tree.x = pos[x];tree.y = len[x];tree.updata(1, n, 1);}}}return 0;
}

Codeforces 877 E Danil and a Part-time Job(线段树+dfs序)相关推荐

  1. CodeForces - 620E New Year Tree(线段树+dfs序+状态压缩)

    题目链接:点击查看 题目大意:给出一棵无向树,每个节点都有一种颜色,接下来时m次操作: 1 x y:将x及其子树染成y的颜色 2 x:查询x及其子树上共有多少种不同的颜色 题目分析:看完这个题的第一反 ...

  2. Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树扫描线

    D. Vika and Segments 题目连接: http://www.codeforces.com/contest/610/problem/D Description Vika has an i ...

  3. BZOJ 3836 Codeforces 280D k-Maximum Subsequence Sum (模拟费用流、线段树)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=3836 (Codeforces) http://codeforces.com ...

  4. Codeforces Beta Round #75 (Div. 1 Only) B. Queue 线段树。单点更新

    http://codeforces.com/problemset/problem/91/B 题意: 给你n个数,求得i 到n中小于a[i]的最右边的a[j],然后求a[i]到a[j]之间包含了多少个数 ...

  5. Codeforces Round #737 (Div. 2) D. Ezzat and Grid 线段树动态开点

    传送门 文章目录 题意: 思路: 题意: 思路: 比较套路的一个题,我们维护一个dp[i]dp[i]dp[i]表示到了第iii行能保留的区间最多是多少. 转移比较明显:dp[i]=max(dp[j]) ...

  6. Codeforces Round #742 (Div. 2) E. Non-Decreasing Dilemma (线段树维护区间连续问题)

    题意: 操作1:把x位置的数字修改成y. 操作2:查询[l,r]之间不下降序列的个数. 题解: 线段树维护区间和问题 (这是套路,想不到只能说做题少别打我) . 用五个变量进行维护. sum区间总个数 ...

  7. CodeForces - 817F MEX Queries(线段树lazy序)

    题目链接:点击查看 题目大意:初始时有一个空的集合,需要执行 n 次操作: 1 l r:将区间 [ l , r ] 内未出现的数加入到集合中 2 l r:将区间 [ l , r ] 内出现的数字全部删 ...

  8. Codeforces Round #686 (Div. 3) F. Array Partition 二分 + 线段树

    传送门 文章目录 题意: 思路: 题意: 化简一下题意就是求满足max(1,x)=min(x+1,y)=max(y+1,n)max(1,x)=min(x+1,y)=max(y+1,n)max(1,x) ...

  9. [Codeforces Round #254 div1] C.DZY Loves Colors 【线段树】

    题目链接:CF Round #254 div1 C 题目分析 这道题目是要实现区间赋值的操作,同时还要根据区间中原先的值修改区间上的属性权值. 如果直接使用普通的线段树区间赋值的方法,当一个节点表示的 ...

最新文章

  1. android edittext email,Android上EditText上的电子邮件地址验证
  2. 从零开始实现主成分分析(PCA)算法
  3. python变量使用前必须先声明、并且一旦声明_初学者学习Python的30天‍-第18天-文件处理...
  4. 如何界定你的竞争对手?
  5. 用C#获取当前的路径
  6. 英语四六级听力有线传输无线发射系统方案
  7. 【精彩文章】数学家论数学——数学的本质
  8. 贝壳雕刻者怎样才能创造出更好的作品
  9. pandas分析NBA2017-2018赛季球员球队数据
  10. Element 之loading颜色修改
  11. Excel技巧—两招轻松搞定汉字转拼音
  12. 如何一个办公室里共享一个打印机,局域网设置打印机共享步骤。超简单,不懂技术都可操作
  13. antd踩坑记录之upload上传
  14. @keyup.enter失效问题
  15. Remix快速导入本地文件夹
  16. 出圈游戏c语言用指针求,出圈游戏程序设计.doc
  17. Anaconda创建新环境及在pycharm中的设置
  18. 【JavaSE基础】08-集合框架(三)
  19. 易验:APP一键登录,就这么简单
  20. 华为认证HCNA-IoT物联网工程师培训 V1.0

热门文章

  1. 关于office2016卸载后注册表残留无法重新安装问题解决
  2. LightGBM算法详解(教你一文掌握LightGBM所有知识点)
  3. 【ubuntu16.04 LTS】ping百度通,但浏览器打不开百度网页
  4. [转载]软件常见的各种版本英文缩写
  5. 服务器如何数据备份?
  6. r语言kmeans聚类(真实案例完整流程)
  7. [TED]丹·吉尔伯特:我们为什么快乐?
  8. 深入理解SimpleChannelInboundHandler
  9. 微信中域名网站域名被封锁、被屏蔽、被和谐后的解决方法
  10. 学习记录297@python全字符匹配