Codeforces Round #877 (Div. 2) E. Danil and a Part-time Job
E. Danil and a Part-time Job
题目链接:http://codeforces.com/contest/877/problem/E
time limit per test2 seconds
memory limit per test256 megabytes
Danil decided to earn some money, so he had found a part-time job. The interview have went well, so now he is a light switcher.
Danil works in a rooted tree (undirected connected acyclic graph) with n vertices, vertex 1 is the root of the tree. There is a room in each vertex, light can be switched on or off in each room. Danil’s duties include switching light in all rooms of the subtree of the vertex. It means that if light is switched on in some room of the subtree, he should switch it off. Otherwise, he should switch it on.
Unfortunately (or fortunately), Danil is very lazy. He knows that his boss is not going to personally check the work. Instead, he will send Danil tasks using Workforces personal messages.
There are two types of tasks:
pow v describes a task to switch lights in the subtree of vertex v.
get v describes a task to count the number of rooms in the subtree of v, in which the light is turned on. Danil should send the answer to his boss using Workforces messages.
A subtree of vertex v is a set of vertices for which the shortest path from them to the root passes through v. In particular, the vertex v is in the subtree of v.
Danil is not going to perform his duties. He asks you to write a program, which answers the boss instead of him.
Input
The first line contains a single integer n (1 ≤ n ≤ 200 000) — the number of vertices in the tree.
The second line contains n - 1 space-separated integers p2, p3, …, pn (1 ≤ pi < i), where pi is the ancestor of vertex i.
The third line contains n space-separated integers t1, t2, …, tn (0 ≤ ti ≤ 1), where ti is 1, if the light is turned on in vertex i and 0 otherwise.
The fourth line contains a single integer q (1 ≤ q ≤ 200 000) — the number of tasks.
The next q lines are get v or pow v (1 ≤ v ≤ n) — the tasks described above.
Output
For each task get v print the number of rooms in the subtree of v, in which the light is turned on.
解题心得:
- 题意是给你一个树,每个节点可以点亮,有q次询问,每次可以询问以i为根的子树下面有多少个亮着的节点,也可以反转以i为根的子树下面的节点的状态(上面所述都包括i节点)。
- 看题意有点线段树的意思,当是线段树是标准的二叉树,所以需要将这个树进行处理,可以树链剖分,但是就这个题来说可以写个dfs序处理,处理后得到一段一段的区间,每个区间代表一个原节点子树的范围,每个区间的左边界就是二叉树最下面的节点(1-n),而询问每个原节点就是询问二叉树中区间的值,注意lazy标记。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+100;
struct node
{
int l,r,sum;
}bitree[maxn*4];
int lef[maxn],rig[maxn];
int lazy[maxn*4];
bool temp[maxn];
vector <int> ve[maxn];
int tot = 1;
//dfs序处理
void dfs(int nod)
{
lef[nod] = tot;
for(int i=0;i<ve[nod].size();i++)
{
tot++;
dfs(ve[nod][i]);
}
rig[nod] = tot;
}
void pushdown(int nod)
{
if(!lazy[nod] || bitree[nod].l == bitree[nod].r)
return ;
lazy[nod] ^= 1;
int l = bitree[nod].l;
int r = bitree[nod].r;
int mid = (bitree[nod].l + bitree[nod].r )/2;
bitree[nod<<1].sum = mid-l+1-bitree[nod<<1].sum;
bitree[nod<<1|1].sum = r-mid-bitree[nod<<1|1].sum;
lazy[nod<<1] ^= 1;
lazy[nod<<1|1] ^= 1;
bitree[nod].sum = bitree[nod<<1].sum + bitree[nod<<1|1].sum;
}
int get_ans(int nod,int l,int r,int L,int R)
{
pushdown(nod);
int mid = (L+R)/2;
if(L>=l && R<=r)
return bitree[nod].sum;
else if(mid < l)
return get_ans(nod<<1|1,l,r,mid+1,R);
else if(mid >= r)
return get_ans(nod<<1,l,r,L,mid);
else
return get_ans(nod<<1,l,mid,L,mid) + get_ans(nod<<1|1,mid+1,r,mid+1,R);
}
void init_bitree(int nod,int L,int R)
{
bitree[nod].l = L;
bitree[nod].r = R;
if(L == R)
{
if(temp[L])
bitree[nod].sum = 1;
return ;
}
int mid = (L + R) / 2;
init_bitree(nod<<1|1,mid+1,R);
init_bitree(nod<<1,L,mid);
bitree[nod].sum = bitree[nod<<1].sum + bitree[nod<<1|1].sum;
}
//lazy标记
void make_lazy(int nod,int l,int r,int L,int R)
{
pushdown(nod);
if(L>=l && R<=r)
{
lazy[nod] ^=1;
bitree[nod].sum = r - l + 1 - bitree[nod].sum;
return ;
}
int mid = (L + R) / 2;
if(mid >= r)
make_lazy(nod<<1,l,r,L,mid);
else if(mid < l)
make_lazy(nod<<1|1,l,r,mid+1,R);
else
{
make_lazy(nod<<1,l,mid,L,mid);
make_lazy(nod<<1|1,mid+1,r,mid+1,R);
}
bitree[nod].sum = bitree[nod<<1].sum + bitree[nod<<1|1].sum;
}
int main()
{
memset(bitree,0,sizeof(bitree));
int n;
scanf("%d",&n);
for(int i=2;i<=n;i++)
{
int now;
scanf("%d",&now);
ve[now].push_back(i);
}
dfs(1);
for(int i=1;i<=n;i++)
{
int now;
scanf("%d",&now);
if(now)
temp[lef[i]] = true;
}
init_bitree(1,1,n);
int q;
scanf("%d",&q);
while(q--)
{
char s[100];
int Node;
scanf("%s%d",s,&Node);
int ans = 0;
if(s[0] == 'p')
make_lazy(1,lef[Node],rig[Node],1,n);
if(s[0] == 'g')
{
ans = get_ans(1,lef[Node],rig[Node],1,n);
printf("%d\n",ans);
}
}
return 0;
}
Codeforces Round #877 (Div. 2) E. Danil and a Part-time Job的更多相关文章
- Codeforces Round #877 (Div. 2) D. Olya and Energy Drinks
题目链接:http://codeforces.com/contest/877/problem/D D. Olya and Energy Drinks time limit per test2 seco ...
- Codeforces Round #877 (Div. 2) B. - Nikita and string
题目链接:http://codeforces.com/contest/877/problem/B Nikita and string time limit per test2 seconds memo ...
- Codeforces Round #442 (Div. 2) E Danil and a Part-time Job (dfs序加上一个线段树区间修改查询)
题意: 给出一个具有N个点的树,现在给出两种操作: 1.get x,表示询问以x作为根的子树中,1的个数. 2.pow x,表示将以x作为根的子树全部翻转(0变1,1变0). 思路:dfs序加上一个线 ...
- Codeforces Round #366 (Div. 2) ABC
Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...
- Codeforces Round #354 (Div. 2) ABCD
Codeforces Round #354 (Div. 2) Problems # Name A Nicholas and Permutation standard input/out ...
- Codeforces Round #368 (Div. 2)
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
- Codeforces Round #279 (Div. 2) ABCDE
Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name A Team Olympiad standard input/outpu ...
- Codeforces Round #262 (Div. 2) 1003
Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...
随机推荐
- bryce1010专题训练——LCA
1.Targan算法(离线) http://poj.org/problem?id=1470 /*伪代码 Tarjan(u)//marge和find为并查集合并函数和查找函数 { for each(u, ...
- Jasper_table_resolve multiple copies of table in detail band issue
resolve method: (1) put table component into the Title band / Page Header band / Summary band, not i ...
- @Results( 中 params 怎么用
http://blog.csdn.net/z69183787/article/details/16342553 struts2的@Result annotation 如何添加params,并且在页面取 ...
- PHP采集利器 Snoopy 试用心得
Snoopy是什么? Snoopy是一个php类,用来模仿web浏览器的功能,它能完成获取网页内容和发送表单的任务. Snoopy的一些特点: * 方便抓取网页的内容 * 方便抓取网页的文本内容 (去 ...
- js 跨浏览器实现事件
我们知道不同的浏览器实现事件是不同的,就比如说我们常见的有三种方法: 1,dom0处理事件的方法,以前的js处理事件都是这样写的. (function () { var p=document.getE ...
- Sublime的用法
一.首先安装插件 1.安装Package Control,这是为了安装其他插件做基础,它可以方便我们下载其他插件 (1).按Ctrl+`调出console(注:避免热键冲突) (2).粘贴以下代码到命 ...
- iOS Block的本质(一)
iOS Block的本质(一) 1.对block有一个基本的认识 block本质上也是一个oc对象,他内部也有一个isa指针.block是封装了函数调用以及函数调用环境的OC对象. 2.探寻block ...
- MySQL常用函数使用示例
#从指定字符中,随机生成12位字符select substring('0123456789abcdefghijklmnopqrstuvwxyz',floor(0+RAND()*36),12); #显示 ...
- (十四)maven之启动tomcat
前言:在网上找了好几种方法启动web项目.比较好用的是:①在Project Facets勾上Dynamic....,但是这个方法会改变项目结构(把WebContent的东西都弄出来了):②使用jett ...
- java 核心技术卷一笔记 6 .2接口 lambda 表达式 内部类
6.2 接口实例 6.2.1 接口与回调 在java.swing包中有一个Timer类,可以使用它在到达给定的时间间隔时发出通告,假如程序中有一个时钟,就可以请求每秒钟获得一个通告,以便更新时钟的表盘 ...