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.




解题心得:

  1. 题意是给你一个树,每个节点可以点亮,有q次询问,每次可以询问以i为根的子树下面有多少个亮着的节点,也可以反转以i为根的子树下面的节点的状态(上面所述都包括i节点)。
  2. 看题意有点线段树的意思,当是线段树是标准的二叉树,所以需要将这个树进行处理,可以树链剖分,但是就这个题来说可以写个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的更多相关文章

  1. 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 ...

  2. 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 ...

  3. 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序加上一个线 ...

  4. 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 ...

  5. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  6. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

  7. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  8. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

  9. 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 ...

随机推荐

  1. NOIP前计划

    距离NOIp还有13天 距离继续学/退役还有13天 是时候列一波计划了 1. 要学的东西 cdq分治(突然发现cdq分治不太行,而且说不定可以用来代替想不出来的数据结构题) 主席树(写的太少啦,不熟练 ...

  2. Macbook上sublime的C++11弥补bits/stdc++.h的配置

    如果在windows配置过的话这次会容易很多.相关博客很多了,我这里保存一下我借鉴并成功的配置: 关于自己build的C++,文件类型为sublime-build,直接扔在它给出的user文件夹即可, ...

  3. Springboot日志配置探索(主要看logback)(一)

    这篇博客是springboot日志配置探索的第一篇,主要讲默认配置下springboot的logback日志框架的配置(即直接使用是怎样的) 首先,是一个SpringBoot的有关日志的说明文档:ht ...

  4. ASP.NET页面传值的方法

    ASP.NET页面传值的方法 From:Refresh-air 在面试的时候,经常会遇到这样的问题,其实我们会对其中的几种方法比较熟悉,因为项目中经常使用.但是要全面的回答ASP.NET中页面传值的方 ...

  5. c# 实现窗体移动

    一般情况下: .添加下列代码到你的窗体中: #region 轻松移动 bool isInMove; Point oldPoint; void InitializeEasyMove() { isInMo ...

  6. SpringBoot 2.x (11):定时任务与异步任务

    定时任务:有时候我们需要做定时的一些操作,比如统计信息,定时发送邮件等 在SpringBoot中如何进行整合和使用呢? 有哪些方式可以实现定时任务呢? Java自带的java.util.timer: ...

  7. 说说JVM原理?内存泄漏与溢出的区别?何时产生内存泄漏?

    1.JVM原理 JVM是Java Virtual Machine(Java虚拟机)的缩写,它是整个java实现跨平台的最核心的部分,所有的Java程序会首先被编译为.class的类文件,这种类文件可以 ...

  8. CF747D Winter Is Coming

     题目链接: http://codeforces.com/problemset/problem/747/D 题目大意: 接下来的n天内每天都有一个气温,如果某天的温度为负数,则必须使用冬季轮胎:而温度 ...

  9. bin&sbin 命令作用

    最近需要了解sbin与bin的功能,需要整理一下.一下全部为Ubuntu14里面默认安装的.在这里收集一下,转载请注明出处! bin bash shell bunzip2 .bz2文件的解压缩程序. ...

  10. 【转】Create Hello-JNI with Android Studio

    [转]Create Hello-JNI with Android Studio From:https://codelabs.developers.google.com/codelabs/android ...