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 ...
随机推荐
- 关于linux网络基础记录
1.linux操作系统是一套非常稳定的操作系统,作用永不止于提供网络服务那么简单.(www.Mail.FTP.DNS.DHCP.NAT.Router) 2.对于一个服务器而言,“搭建容易维护难”:维护 ...
- Linux下编译、安装并启动apache
安装步骤如下: 1. 首先去http://httpd.apache.org/download.cgi上下载需要的apache源码,然后存放至/usr/local/src下[此源码存放路径可任意指定] ...
- Delphi 画箭头
procedure TForm1.Line(x, y, x2, y2: integer); begin canvas.MoveTo(x, y); canvas.LineTo(x2, y2); end; ...
- bootstrap 自定义
在ror工程内 /app/assets/stylesheets/bootstrap_and_overrides.css.less 内覆盖内容 具体参数如下 https://github.com/twb ...
- Redis 主从同步配置
主从功能: 为了防止 Redis 磁盘损坏,导致数据丢失,Redis 提供了复制功能,将一个主数据库的数据自动同步到从数据库,防止数据丢失. 同时还可以配置一主多从来分担主压力,主只接受写的操作,将读 ...
- 如何了解一个Web项目
一:学会如何读一个JavaWeb项目源代码 步骤:表结构->web.xml->mvc->db->spring ioc->log->代码 1.先了解项目数据库的表结构 ...
- 理解python中的元类
一,理解类也是对象 在python中类同样也是一种对象,只要使用关键字class,Python解释器在执行的时候就会创建一个对象,这个对象(类)自身拥有创建对象(类实例)的能力,这就是为什么他是一个类 ...
- 第一个Django应用程序_part3
一.概述 此文延续第一个Django应用程序part2. 官方文档:https://docs.djangoproject.com/en/1.11/intro/tutorial03/ view是Djan ...
- TortoiseSVN教程
TortoiseSVN使用教程 TortoiseSVN是一个SVN的客户端 1.Checkout Repository 首先要Checkout服务器端的Repository,所谓的Checkout就是 ...
- Python爬虫实战五之模拟登录淘宝并获取所有订单
经过多次尝试,模拟登录淘宝终于成功了,实在是不容易,淘宝的登录加密和验证太复杂了,煞费苦心,在此写出来和大家一起分享,希望大家支持. 温馨提示 更新时间,2016-02-01,现在淘宝换成了滑块验证了 ...