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 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.
Example
inputCopy
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
outputCopy
2
0
0
1
2
1
1
0
Note

The tree before the task pow 1.

The tree after the task pow 1.
题意:给出一棵树初始的节点值,给出两种操作,一种为子树异或1,另一种为统计子树中一的个数
题解: 可以用dfs序+线段树解决,异或标记可以通过tag[x]^=1来进行传递,每次更改相当于将区间内所有的1改为0,所有的0改为1,这样相当于把sum改为size-sum,可以O(1)实现
代码如下:
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lson root<<1
#define rson root<<1|1
using namespace std; struct node
{
int l,r,lazy,sum;
} tr[]; vector<int> g[];
int id[],size[],c[],w[],tot; void push_up(int root)
{
tr[root].sum=tr[lson].sum+tr[rson].sum;
} void push_down(int root)
{
int mid=(tr[root].l+tr[root].r)>>;
tr[lson].sum=(mid-tr[root].l+)-tr[lson].sum;
tr[lson].lazy=^tr[lson].lazy;
tr[rson].sum=(tr[root].r-mid)-tr[rson].sum;
tr[rson].lazy=^tr[rson].lazy;
tr[root].lazy=;
} void build(int root,int l,int r)
{
if(l==r)
{
tr[root].l=l;
tr[root].r=r;
tr[root].sum=w[l];
return ;
}
tr[root].l=l;
tr[root].r=r;
int mid=(l+r)>>;
build(lson,l,mid);
build(rson,mid+,r);
push_up(root);
} void update(int root,int l,int r,int val)
{
if(tr[root].l==l&&tr[root].r==r)
{
tr[root].sum=(tr[root].r-tr[root].l+)-tr[root].sum;
tr[root].lazy=tr[root].lazy^;
return ;
}
if(tr[root].lazy)
{
push_down(root);
}
int mid=(tr[root].l+tr[root].r)>>;
if(l>mid)
{
update(rson,l,r,val);
}
else
{
if(mid>=r)
{
update(lson,l,r,val);
}
else
{
update(lson,l,mid,val);
update(rson,mid+,r,val);
}
}
push_up(root);
} int query(int root,int l,int r)
{
if(tr[root].l==l&&tr[root].r==r)
{
return tr[root].sum;
}
if(tr[root].lazy)
{
push_down(root);
}
int mid=(tr[root].l+tr[root].r)>>;
if(mid<l)
{
return query(rson,l,r);
}
else
{
if(mid>=r)
{
return query(lson,l,r);
}
else
{
return query(lson,l,mid)+query(rson,mid+,r);
}
}
} void dfs(int now,int f)
{
id[now]=++tot;
w[tot]=c[now];
size[now]=;
for(int i=; i<g[now].size(); i++)
{
if(g[now][i]==f)
{
continue;
}
dfs(g[now][i],now);
size[now]+=size[g[now][i]];
}
} void sub_update(int u,int val)
{
update(,id[u],id[u]+size[u]-,val);
} int sub_query(int u)
{
return query(,id[u],id[u]+size[u]-);
} int main()
{
int n,m;
scanf("%d",&n);
for(int i=; i<=n; i++)
{
int to;
scanf("%d",&to);
g[to].push_back(i);
g[i].push_back(to);
}
for(int i=; i<=n; i++)
{
scanf("%d",&c[i]);
}
dfs(,);
build(,,n);
scanf("%d",&m);
char s[];
int val;
for(int i=; i<=m; i++)
{
scanf("\n%s %d",s,&val);
if(s[]=='g')
{
printf("%d\n",sub_query(val));
}
else
{
sub_update(val,);
}
}
}
CodeForces 877E Danil and a Part-time Job(dfs序+线段树)的更多相关文章
- Codeforces 877E Danil and a Part-time Job(dfs序 + 线段树)
题目链接 Danil and a Part-time Job 题意 给出一系列询问或者修改操作 $pow$ $x$表示把以$x$为根的子树的所有结点的状态取反($0$变$1$,$1$变$0$ ...
- 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 Round #225 (Div. 2) E. Propagating tree dfs序+-线段树
题目链接:点击传送 E. Propagating tree time limit per test 2 seconds memory limit per test 256 megabytes inpu ...
- CodeForces 877E DFS序+线段树
CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...
- Codeforces Round #442 (Div. 2)A,B,C,D,E(STL,dp,贪心,bfs,dfs序+线段树)
A. Alex and broken contest time limit per test 2 seconds memory limit per test 256 megabytes input s ...
- Codeforces 838B - Diverging Directions - [DFS序+线段树]
题目链接:http://codeforces.com/problemset/problem/838/B You are given a directed weighted graph with n n ...
- Educational Codeforces Round 6 E dfs序+线段树
题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色 比较容易想到dfs序+线段树去做 dfs序是很久以前看的bilibili ...
- Codeforces 343D Water Tree(DFS序 + 线段树)
题目大概说给一棵树,进行以下3个操作:把某结点为根的子树中各个结点值设为1.把某结点以及其各个祖先值设为0.询问某结点的值. 对于第一个操作就是经典的DFS序+线段树了.而对于第二个操作,考虑再维护一 ...
- Codeforces 620E New Year Tree(DFS序 + 线段树)
题目大概说给一棵树,树上结点都有颜色(1到60),进行下面两个操作:把某结点为根的子树染成某一颜色.询问某结点为根的子树有多少种颜色. 子树,显然DFS序,把子树结点映射到连续的区间.而注意到颜色60 ...
随机推荐
- Julia - 字符串判断函数
isascii() 判断是否是 ascii 码,返回 Bool 值 julia> isascii('a') true julia> isascii('α') false julia> ...
- sql developer Oracle 数据库 用户对象下表及表结构的导入导出
Oracle数据库表数据及结构的导入导出 导出的主机与即将导入到的目标主机的tablespace 及用户名需一直!!!!!
- 「小程序JAVA实战」小程序的表单组件(25)
转自:https://idig8.com/2018/08/18/xiaochengxujavashizhanxiaochengxudebiaodanzujian25/ 来说下 ,小程序的基础组件.源码 ...
- RHCE7 学习里程-3基本命令
一.centos7 基本命令 #创建文件 touch a.b #创建文件夹 mkdir abc #删除文件 rm -f a.b #删除空文件夹 rm -rf abc #重命名文件 mv 源文件 新文 ...
- Redis实战——redis主从备份和哨兵模式实践
借鉴:http://redis.majunwei.com/topics/sentinel.html https://blog.csdn.net/u011784767/article/detai ...
- VB导入Excel到数据库软件(持续更新中。)
1.选择Excel文件版本 电脑上用的 Office2010 引用:Mircosoft Excel 14.0 Object Library 2.选择Excel文件 '选择文件公共变量 Public D ...
- MaxScript 学习笔记【有转载】
1. string string类型的变量是一个数组,下列操作合法:strName = $.name -- output: "Shemmy_03" strName[1] --得到字 ...
- spring security的原理及教程
spring security使用分类: 如何使用spring security,相信百度过的都知道,总共有四种用法,从简到深为:1.不用数据库,全部数据写在配置文件,这个也是官方文档里面的demo: ...
- iOS学习之iOS沙盒(sandbox)机制和文件操作之NSFileManager
我们看看NSFileManager如何使用.包括创建文件,目录,删除,遍历目录等. 1.在Documents里创建目录 创建一个叫test的目录,先找到Documents的目录, [cpp] view ...
- unity配置最簡單程序
using System;using System.Collections.Generic;using System.Linq;using System.Text;using Microsoft.Pr ...