codeforces 877e
2 seconds
256 megabytes
standard input
standard output
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.
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 0otherwise.
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.
For each task get v print the number of rooms in the subtree of v, in which the light is turned on.
4
1 1 1
1 0 0 1
9
get 1
get 2
get 3
get 4
pow 1
get 1
get 2
get 3
get 4
2
0
0
1
2
1
1
0 题意:n点 输入每个点的值0或1 输入每个点的父节点 m次操作 pow操作改变q节点后面的全部节点包括q节点 get操作是问q节点的子节点包括q一共有多少个1
这个题要用线段树+dfs,意思就是为每个点分配一个区间,区间大的包含区间小的
这个题要注意的是
每个点可能变换多次,你不需要全都变换,查询时候在一次性的变完就行,否则可能会超时,反正我链表这样做超时了,数组我好像runtime error了 最后也懒得改了,又敲了一遍过的,然后就没什么注意的了,这题就是这样
丑陋的代码
#include <iostream>
#include <vector>
using namespace std;
void pushdown(int i);
const int N = 2e5 + 10;
int a[N],in[N],out[N],pre[N],cnt = 0;
vector<int> p[N];
struct node
{
int l = 0,r = 0;
int sum = 0;
int lazy = 0;
}pp[N<<2];
void dfs(int n)
{
for(int i = 0; i < p[n].size(); ++i)
{
int d = p[n][i];
cnt ++;
in[d] = cnt;
pre[cnt] = d;
dfs(d);
out[d] = cnt;
}
}
void build(int i)
{
int mid = (pp[i].l+pp[i].r)>>1;
int l = pp[i].l;
int r = pp[i].r;
if(pp[i].l == pp[i].r)
{
pp[i].sum = a[pre[l]];
return ;
}
pp[(i<<1)].l = l;
pp[(i<<1)].r = mid;
pp[(i<<1)+1].l = mid+1;
pp[(i<<1)+1].r = r;
build((i<<1));
build((i<<1)+1);
pp[i].sum += pp[i<<1].sum + pp[(i<<1)+1].sum;
}
void update(int l,int r,int i)
{
int mid = (pp[i].l+pp[i].r) >> 1;
if(pp[i].l == l && pp[i].r == r)
{
pp[i].sum = pp[i].r - pp[i].l + 1 - pp[i].sum;
pp[i].lazy ^= 1;
pushdown(i);
//这个地方要注意pushdowm的操作位置
return ;
}
if(r <= mid)
{
update(l,r, i<<1);
}
else if(l >= mid + 1)
{
update(l,r,(i<<1)+1);
}
else
{
update(l, mid, i<<1);
update(mid+1, r, (i<<1)+1);
}
pp[i].sum = pp[i<<1].sum + pp[(i<<1)+1].sum;
}
void pushdown(int i)
{
if(pp[i].lazy)
{
pp[i].sum = pp[i].r - pp[i].l + 1 - pp[i].sum;
pp[i<<1].lazy ^= 1;
pp[(i<<1)+1].lazy ^= 1;
pp[i].lazy ^= 1;
}
}
int query(int l,int r,int i)
{
int mid = (pp[i].l + pp[i].r)>>1;
pushdown(i);
if(pp[i].l == l && pp[i].r == r)
return pp[i].sum;
if(r <= mid)
{
return query(l, r, i<<1);
}
else if(l >= mid + 1)
{
return query(l, r, (i<<1)+1);
}
else
{
return query(l, mid, i<<1) + query(mid+1, r, (i<<1)+1);
}
}
int main()
{
int n,i,j,d,x,ppp;
char str[20];
scanf("%d",&n);
for(i = 2; i <= n; ++i)
{
scanf("%d",&d);
p[d].push_back(i);
}
for(i = 1; i <= n; ++i)
scanf("%d",&a[i]);
pre[1] = 1;
cnt = 1;
in[1] = 1;
out[1] = n;
pp[1].l = 1;
pp[1].r = n;
dfs(1);
build(1);
scanf("%d",&ppp);
while( ppp-- )
{
scanf("%s",str);
if(str[0] == 'g')
{
scanf("%d",&x);
printf("%d\n",query(in[x], out[x], 1));
}
else
{
scanf("%d",&x);
update(in[x], out[x], 1);
}
}
return 0;
}
注意 update的时候假如(pp[i].l == l && pp[i].r == r)这个时候一定要更新当前节点 后面的节点可以不更新,但当前节点必须要更新
具体原因数据在这里 你画一下图就明白了
10
1 2 3 3 5 5 7 7 8
0 0 0 0 1 1 1 1 0 0
10
pow 3
get 1
pow 9
get 1
get 1
get 8
pow 8
pow 4
get 10
pow 2
codeforces 877e的更多相关文章
- CodeForces 877E DFS序+线段树
CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...
- Codeforces 877E - Danil and a Part-time Job(dfs序+线段树)
877E - Danil and a Part-time Job 思路:dfs序+线段树 dfs序:http://blog.csdn.net/qq_24489717/article/details/5 ...
- [Codeforces 877E] Danil and a Part-time Job
[题目链接] https://codeforces.com/contest/877/problem/E [算法] 首先求出这棵树的DFS序 一棵子树的DFS序为连续的一段 , 根据这个性质 , 用线段 ...
- Codeforces 877E - Danil and a Part-time Job 线段树+dfs序
给一个有根树,1e5个节点,每个节点有权值0/.1,1e5操作:1.将一个点的子树上所有点权值取反2.查询一个点的子树的权值和 题解: 先深搜整颗树,用dfs序建立每个点对应的区间,等于把树拍扁成 ...
- CodeForces 877E Danil and a Part-time Job(dfs序+线段树)
Danil decided to earn some money, so he had found a part-time job. The interview have went well, so ...
- Codeforces 877E Danil and a Part-time Job(dfs序 + 线段树)
题目链接 Danil and a Part-time Job 题意 给出一系列询问或者修改操作 $pow$ $x$表示把以$x$为根的子树的所有结点的状态取反($0$变$1$,$1$变$0$ ...
- python爬虫学习(5) —— 扒一下codeforces题面
上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
- 【Codeforces 738C】Road to Cinema
http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...
随机推荐
- 8I - 吃糖果
HOHO,终于从Speakless手上赢走了所有的糖果,是Gardon吃糖果时有个特殊的癖好,就是不喜欢将一样的糖果放在一起吃,喜欢先吃一种,下一次吃另一种,这样:可是Gardon不知道是否存在一种吃 ...
- poj 1182 (关系并查集) 食物链
题目传送门:http://poj.org/problem?id=1182 这是一道关系型并查集的题,对于每个动物来说,只有三种情况:同类,吃与被吃: 所以可以用0,1,2三个数字代表三种情况,在使用并 ...
- LINUX查看网卡UUID
有时我们不小心将/etc/sysconfig/network-scripts/ifcfg-eth0(可以通过此文件进行查看UUID)删除或者损坏,要重新编辑ifcfg-eth0文件时不知道网卡的UUI ...
- BZOJ1047或洛谷2216 [HAOI2007]理想的正方形
BZOJ原题链接 洛谷原题链接 显然可以用数据结构或\(ST\)表或单调队列来维护最值. 这里采用单调队列来维护. 先用单调队列维护每一行的最大值和最小值,区间长为正方形长度. 再用单调队列维护之前维 ...
- Luogu 1415-拆分数列-动态规划
Solution 首先要找到使得最后一个数最小, 只需定义一个数组$pre[i]$ 从区间$[pre[i], i]$表示的数, 是最小的能使前面的数递增的方案. $[ pre[n], n]$即为最小的 ...
- 谁说delphi没有IOCP库,delphi新的IOCP类库,开源中: DIOCP组件JSON流模块说明
单元:JSonStream.pas 简介:本单元实现 流和json对象的相互转换,其中有一些保留的key. 依赖:superobject 保留key: __result.errCode 返回的错误编 ...
- 谁说delphi没有IOCP库,delphi新的IOCP类库,开源中
DIOCP Demo说明 下载地址 https://code.google.com/p/diocp/ 特地为DIOCP开设了一个群:320641073,欢迎学习的IOCP的童鞋进入讨论. 核心作者: ...
- chrome、firefox表单自动提交诱因 -- 非type=hidden的单输入域(input)
开发任务中遇到很费解的一个form自动提交问题,form中只有一个input时回车会触发自动提交表单,当在多一个非type=hidden的input时,又不会出现表单自动提交. 代码示例: 会出现自动 ...
- 2017/2/14:JSTL标签与el表达式
一.JSTL标签介绍 1.什么是JSTL? JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL),JSTL是标签语言!JSTL标签使用以来非常方便,它与JSP动作标签一样,只不过它不是 ...
- Mac网络命令 老命令重新学
网络与通信操作 命令名 功能描述 使用举例 telnet 远程登录 telnet hpc.sp.net.edu.cn rlogin 远程登录 rlogin hostname -l username r ...