博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
codeforces 877 E. Danil and a Part-time Job(线段树(dfs序))
阅读量:5306 次
发布时间:2019-06-14

本文共 2715 字,大约阅读时间需要 9 分钟。

题目链接:

 

题解:显然一看就感觉要么树链剖分要么线段树+dfs序,题目要求的操作显然用线段树+dfs序就可以实现。然后就敲一下线段树+dfs序就行挺简单的只要dfs一遍记录当前节点的下表然后再加一个leng数组来存子树最多到达几然后更新或者求值的时候只要查询(pos[x],leng[x])即可。

#include 
#include
#include
#include
#define lson (i << 1)#define rson ((i << 1) | 1)using namespace std;const int M = 2e5 + 10;int a[M] , pos[M] , leng[M] , pre[M] , cnt;vector
vc[M];struct TnT { int l , r , sum , lazy;}T[M << 2];void push_up(int i) { T[i].sum = T[lson].sum + T[rson].sum;}void push_down(int i) { if(T[i].lazy) { T[lson].sum = T[lson].r - T[lson].l + 1 - T[lson].sum; T[rson].sum = T[rson].r - T[rson].l + 1 - T[rson].sum; T[lson].lazy ^= 1; T[rson].lazy ^= 1; T[i].lazy = 0; }}void build(int l , int r , int i) { int mid = (l + r) >> 1; T[i].l = l , T[i].r = r , T[i].sum = 0 , T[i].lazy = 0; if(l == r) { T[i].sum = a[pre[l]]; return ; } push_down(i); build(l , mid , lson); build(mid + 1 , r , rson); push_up(i);}void update(int l , int r , int i) { int mid = (T[i].l + T[i].r) >> 1; if(T[i].l == l && T[i].r == r) { T[i].sum = (T[i].r - T[i].l + 1) - T[i].sum; T[i].lazy ^= 1; return ; } push_down(i); if(mid < l) { update(l , r , rson); } else if(mid >= r) { update(l , r , lson); } else { update(l , mid , lson) , update(mid + 1 , r , rson); } push_up(i);}int query(int l , int r , int i) { int mid = (T[i].l + T[i].r) >> 1; if(T[i].l == l && T[i].r == r) { return T[i].sum; } push_down(i); if(mid < l) { return query(l , r , rson); } else if(mid >= r) { return query(l , r , lson); } else { return query(l , mid , lson) + query(mid + 1 , r , rson); }}void dfs(int u) { int len = vc[u].size(); for(int i = 0 ; i < len ; i++) { int v = vc[u][i]; pos[v] = ++cnt; pre[cnt] = v; dfs(v); leng[v] = cnt; }}int main() { int n , x , q; char s[123]; scanf("%d" , &n); for(int i = 2 ; i <= n ; i++) { scanf("%d" , &x); vc[x].push_back(i); } for(int i = 1 ; i <= n ; i++) { scanf("%d" , &a[i]); } scanf("%d" , &q); cnt = 0; pos[1] = ++cnt; pre[cnt] = 1; leng[1] = n; dfs(1); build(1 , n , 1); while(q--) { scanf("%s" , s); if(s[0] == 'g') { scanf("%d" , &x); printf("%d\n" , query(pos[x] , leng[x] , 1)); } else { scanf("%d" , &x); update(pos[x] , leng[x] , 1); } } return 0;}

 

转载于:https://www.cnblogs.com/TnT2333333/p/7721193.html

你可能感兴趣的文章
生成随机的数字和字母组合
查看>>
File类
查看>>
java学习-1
查看>>
unigui的菜单树补习【2】treeview
查看>>
Qt 获取屏幕信息
查看>>
dubbo注册服务IP解析异常及IP解析源码分析
查看>>
java_位运算符
查看>>
java_基础语法之while语句
查看>>
个人经验 - Android的RelativeLayout布局的layout_height属性设置为wrap_content时的坑
查看>>
最长子序列
查看>>
SQL分组查询每组前几条数据
查看>>
01章 面向对象开发方法概述
查看>>
命令行调用Lame批量压缩MP3
查看>>
iis7配置网站容易出现的问题(转)
查看>>
如何成为一名优秀的程序员?
查看>>
HDU(4528),BFS,2013腾讯编程马拉松初赛第五场(3月25日)
查看>>
C++期中考试
查看>>
Working with Characters and Strings(Chapter 2 of Windows Via C/C++)
查看>>
vim中文帮助教程
查看>>
Android 创建与解析XML(四)—— Pull方式
查看>>