codeforces 877 E. Danil and a Part-time Job(线段树(dfs序))
题目链接:http://codeforces.com/contest/877/problem/E
题解:显然一看就感觉要么树链剖分要么线段树+dfs序,题目要求的操作显然用线段树+dfs序就可以实现。然后就敲一下线段树+dfs序就行挺简单的只要dfs一遍记录当前节点的下表然后再加一个leng数组来存子树最多到达几然后更新或者求值的时候只要查询(pos[x],leng[x])即可。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#define lson (i << 1)
#define rson ((i << 1) | 1)
using namespace std;
const int M = 2e5 + ;
int a[M] , pos[M] , leng[M] , pre[M] , cnt;
vector<int> vc[M];
struct TnT {
int l , r , sum , lazy;
}T[M << ];
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 + - T[lson].sum;
T[rson].sum = T[rson].r - T[rson].l + - T[rson].sum;
T[lson].lazy ^= ;
T[rson].lazy ^= ;
T[i].lazy = ;
}
}
void build(int l , int r , int i) {
int mid = (l + r) >> ;
T[i].l = l , T[i].r = r , T[i].sum = , T[i].lazy = ;
if(l == r) {
T[i].sum = a[pre[l]];
return ;
}
push_down(i);
build(l , mid , lson);
build(mid + , r , rson);
push_up(i);
}
void update(int l , int r , int i) {
int mid = (T[i].l + T[i].r) >> ;
if(T[i].l == l && T[i].r == r) {
T[i].sum = (T[i].r - T[i].l + ) - T[i].sum;
T[i].lazy ^= ;
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 + , r , rson);
}
push_up(i);
}
int query(int l , int r , int i) {
int mid = (T[i].l + T[i].r) >> ;
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 + , r , rson);
}
}
void dfs(int u) {
int len = vc[u].size();
for(int i = ; 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[];
scanf("%d" , &n);
for(int i = ; i <= n ; i++) {
scanf("%d" , &x);
vc[x].push_back(i);
}
for(int i = ; i <= n ; i++) {
scanf("%d" , &a[i]);
}
scanf("%d" , &q);
cnt = ;
pos[] = ++cnt;
pre[cnt] = ;
leng[] = n;
dfs();
build( , n , );
while(q--) {
scanf("%s" , s);
if(s[] == 'g') {
scanf("%d" , &x);
printf("%d\n" , query(pos[x] , leng[x] , ));
}
else {
scanf("%d" , &x);
update(pos[x] , leng[x] , );
}
}
return ;
}
codeforces 877 E. Danil and a Part-time Job(线段树(dfs序))的更多相关文章
- Codeforces 571D - Campus(并查集+线段树+DFS 序,hot tea)
Codeforces 题目传送门 & 洛谷题目传送门 看到集合的合并,可以本能地想到并查集. 不过这题的操作与传统意义上的并查集不太一样,传统意义上的并查集一般是用来判断连通性的,而此题还需支 ...
- Codeforces 877E - Danil and a Part-time Job 线段树+dfs序
给一个有根树,1e5个节点,每个节点有权值0/.1,1e5操作:1.将一个点的子树上所有点权值取反2.查询一个点的子树的权值和 题解: 先深搜整颗树,用dfs序建立每个点对应的区间,等于把树拍扁成 ...
- Codeforces 343D WaterTree - 线段树, DFS序
Description Translated by @Nishikino_Maki from Luogu 行吧是我翻的 Mad scientist Mike has constructed a roo ...
- Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树)
Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树) 题目链接 题意 给定一个nm的矩阵,每行取2k的矩阵,求总 ...
- Codeforces Round #292 (Div. 1) C. Drazil and Park 线段树
C. Drazil and Park 题目连接: http://codeforces.com/contest/516/problem/C Description Drazil is a monkey. ...
- Codeforces Round #254 (Div. 1) C. DZY Loves Colors 线段树
题目链接: http://codeforces.com/problemset/problem/444/C J. DZY Loves Colors time limit per test:2 secon ...
- 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 ...
- Codeforces Round #337 (Div. 2) D. Vika and Segments (线段树+扫描线+离散化)
题目链接:http://codeforces.com/contest/610/problem/D 就是给你宽度为1的n个线段,然你求总共有多少单位的长度. 相当于用线段树求面积并,只不过宽为1,注意y ...
- Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)
题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题 ...
随机推荐
- 【POJ - 3258】River Hopscotch(二分)
River Hopscotch 直接中文 Descriptions 每年奶牛们都要举办各种特殊版本的跳房子比赛,包括在河里从一块岩石跳到另一块岩石.这项激动人心的活动在一条长长的笔直河道中进行,在起点 ...
- [ PyQt入门教程 ] PyQt5基本控件使用:单选按钮、复选框、下拉框
本文主要介绍PyQt5界面最基本使用的单选按钮.复选框.下拉框三种控件的使用方法进行介绍. 1.RadioButton单选按钮/CheckBox复选框.需要知道如何判断单选按钮是否被选中. 2.Com ...
- Redis分布式锁实战
什么是分布式锁 在单机部署的情况下,要想保证特定业务在顺序执行,通过JDK提供的synchronized关键字.Semaphore.ReentrantLock,或者我们也可以基于AQS定制化锁.单机部 ...
- xcode自动刷新resource下的文件
修改resource下的lua或者ccbi文件时,xcode并不会察觉到,所以需要手动清理xcode缓存和模拟器缓存,开发效率比较低下. 通过以下步骤可以实现自动刷新resource下的文件,且无需手 ...
- IPC机制2
1.使用Messenger Messenger可以翻译为信使,通过它可以在不同进程中传递messenge对象,在messenge中放入我们需要传递的数据,就可以轻松实现数据在进程中传递. 服务段进程: ...
- intellIJ IDEA学习笔记2
常用的有fori/sout/psvm+Tab即可生成循环.System.out.main方法等boilerplate样板代码 例如要输入for(User user : users)只需输入user.f ...
- 从原理层面掌握@ModelAttribute的使用(核心原理篇)【一起学Spring MVC】
每篇一句 我们应该做一个:胸中有蓝图,脚底有计划的人 前言 Spring MVC提供的基于注释的编程模型,极大的简化了web应用的开发,我们都是受益者.比如我们在@RestController标注的C ...
- Java String引起的常量池、String类型传参、“==”、“equals”、“hashCode”问题 细节分析
在学习javase的过程中,总是会遇到关于String的各种细节问题,而这些问题往往会出现在Java攻城狮面试中,今天想写一篇随笔,简单记录下我的一些想法.话不多说,直接进入正题. 1.String常 ...
- 写论文的第三天 自建zookeeper集群
日志___2019.1.25 基于hadoop集群搭建zookeeper集群 Filezilla上传zookeeper压缩包到主节点 安装zookeeper到/usr/local目录 命令:tar – ...
- python + selenium webdriver 从主窗口A跳转至主窗口B后,无法定位窗口B的元素的问题
在做登录脚本的时候,如果只是单纯从登录页面进行元素定位的话,并不存在这个问题 但实际情况是,从首页A进入到登录页面B(并非弹出框),这时候在页面B无法定位到该页面的元素 问题:从页面A进入页面B,无法 ...