您的位置:首页 > 其它

Codeforces Round #442 (Div. 2) E. Danil and a Part-time Job

2017-10-26 20:03 429 查看

E. Danil and a Part-time Job

Problem Statement

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:

1. pow v describes a task to switch lights in the subtree of vertex v.

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

Examples

Example 1

Input

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

Output

2

0

0

1

2

1

1

0

Note



题意

给一颗以节点1为根的树,每个节点上有一盏灯泡,现在给出树的连边情况,和灯泡的初始亮暗状态,有两种操作,第一种操作是将这个节点和这个节点的子树里的所有节点上的灯泡进行翻转(将暗的变成亮的,将亮的变成暗的),另一种操作是询问这个节点的子树(含这个节点)中有几盏亮的灯泡。

思路

一看到是对一颗子树的操作,我们就可以想到根据DFS序来做这题,不过显然,暴力是绝对不能过的。又因为两个操作在DFS序上分别对应区间反转和区间求和,我们很容易就能想到,用线段树维护就行了。所以这题就是DFS序+线段树。

Code

#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>
inline void read(T &x) {
Finish_read=0;x=0;int f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
x*=f;Finish_read=1;
}
template<class T>
inline void print(T x) {
if(x/10!=0)
print(x/10);
putchar(x%10+'0');
}
template<class T>
inline void writeln(T x) {
if(x<0)
putchar('-');
x=abs(x);
print(x);
putchar('\n');
}
template<class T>
inline void write(T x) {
if(x<0)
putchar('-');
x=abs(x);
print(x);
}
/*================Header Template==============*/
#define lb(x) x&(-x)
const int maxn=400020;
vector<int> G[maxn];
int idx,q,n,fa[maxn],st[maxn],ed[maxn],clo,a[maxn],b[maxn];
string s;
#define lson o<<1
#define rson o<<1|1
struct seg_tree{int l,r,sum,lazy;}t[maxn<<2];
inline void pushup(int o){t[o].sum=t[lson].sum+t[rson].sum;}
inline void pushdown(int o) {
if(t[o].lazy) {
t[lson].lazy^=t[o].lazy;
t[rson].lazy^=t[o].lazy;
t[lson].sum=t[lson].r-t[lson].l+1-t[lson].sum;
t[rson].sum=t[rson].r-t[rson].l+1-t[rson].sum;
t[o].lazy=0;
}
}
inline void build(int o,int l,int r) {
t[o].l=l;
t[o].r=r;
if(l==r) {
t[o].sum=a[l];
return;
}
int mid=(l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(o);
}
inline void update(int o,int l,int r,int ql,int qr) {
pushdown(o);
if(t[o].l==ql&&t[o].r==qr) {
t[o].lazy^=1;
t[o].sum=t[o].r-t[o].l+1-t[o].sum;
return;
}
int mid=(l+r)>>1;
if(qr<=mid)
update(lson,l,mid,ql,qr);
else if(ql>mid)
update(rson,mid+1,r,ql,qr);
else {
update(lson,l,mid,ql,mid);
update(rson,mid+1,r,mid+1,qr);
}
pushup(o);
}
inline ll query(int o,int l,int r,int ql,int qr) {
pushdown(o);
if(l==ql&&r==qr)
return t[o].sum;
int mid=(l+r)>>1;
if(qr<=mid)
return query(lson,l,mid,ql,qr);
else if(ql>mid)
return query(rson,mid+1,r,ql,qr);
else
return query(lson,l,mid,ql,mid)+query(rson,mid+1,r,mid+1,qr);
}
inline void dfs(int u) {
st[u]=++clo;
for(unsigned i=0;i<G[u].size();i++) {
int v=G[u][i];
if(v==fa[u])
continue;
dfs(v);
}
ed[u]=clo;
}
int main() {
read(n);
for(int i=2;i<=n;i++) {
read(fa[i]);
G[fa[i]].push_back(i);
}
dfs(1);
for(int i=1;i<=n;i++) {
read(b[i]);
a[st[i]]=b[i];
}
build(1,1,n);
//  for(int i=1;i<=n;i++)
//      cout<<st[i]<<" "<<ed[i]<<endl;
read(q);
while(q--) {
cin>>s;
read(idx);
if(s=="pow")
update(1,1,n,st[idx],ed[idx]);
else
writeln(query(1,1,n,st[idx],ed[idx]));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces
相关文章推荐