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. Qt 进程和线程之四:线程实际应用

    为了让程序尽快响应用户操作,在开发应用程序时经常会使用到线程.对于耗时操作如果不使用线程,UI界面将会长时间处于停滞状态,这种情况是用户非常不愿意看到的,我们可以用线程来解决这个问题. 大多数情况下, ...

  2. bzoj3583 杰杰的女性朋友 || bzoj4362 Graph

    http://210.33.19.103/problem/2174 很显然是矩阵快速幂的题,设有in和ou矩阵,设in矩阵的转置为in' 显然可以直接暴力求出任意两点间走一步路径条数,然后求其d次幂, ...

  3. SecureCRT无法连接虚拟机Linux—虚拟网卡(NAT方式)IP(169.254.xx.xx)无效问题

    搞了一晚上,终于解决了http://blog.csdn.net/zengxianyang/article/details/50394809

  4. python flask学习(1)与Git基础操作

    今天从简单的flask开始完成Flask web开发的学习.今天学习了Git和GitHub项目的提交. Git尝试提交过程中出现了"Could not read from remote re ...

  5. android开发学习 ------- 自定义View 圆 ,其点击事件 及 确定当前view的层级关系

    我需要实现下面的效果:   参考文章:https://blog.csdn.net/halaoda/article/details/78177069 涉及的View事件分发机制 https://www. ...

  6. [原创] SOAP UI 创建SOAP工程进行接口测试

    下载及安装 1. 登录http://www.soapui.org/ 2. 鼠标移动到导航头的Downloads选项 3. 点击SOAP UI 4. 下载页面 新建项目 创建项目 1. 创建项目很简单. ...

  7. sqlite总结1

    I Shell下命令行程序CLP I .help II 命令的简写 .e = .quit .s .h = .help II 数据库管理 A 创建数据库 1 CREATE TABLE id_name(i ...

  8. C# DataTable的詳細用法 (转)

    在项目中经常用到DataTable,如果DataTable使用得当,不仅能使程序简洁实用,而且能够提高性能,达到事半功倍的效果,现对DataTable的使用技巧进行一下总结. 一.DataTable简 ...

  9. SQL server 数据库基础语句

    上篇介绍的是鼠标操作 遗漏两个知识: 主外键 两个列 数据类型 必须一致    //int类型不能约束nvarchar 类型      varchar类型不能约束nvarchar类型 varchar( ...

  10. 洛谷 P1165 日志分析

    题目描述 M 海运公司最近要对旗下仓库的货物进出情况进行统计.目前他们所拥有的唯一记录就是一个记录集装箱进出情况的日志.该日志记录了两类操作:第一类操作为集装箱入库操作,以及该次入库的集装箱重量:第二 ...