Problem Link : http://codeforces.com/contest/877/problem/E
Solution Idea:
Run a dfs on the given for getting the Euler tour order or inorder traversal order. Then the tree is converted to a liner 1D array. Now we can apply range query and update on this array.
Now use a range update query data structure. Here I have used segment tree. Now initialize the tree with the initial value and now our job is to just toggle a subtree of the given tree and perform query operation. Use a propagation for the update and answer the query.
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pii pair <int,int>
#define pll pair <long long,long long>
#define sc scanf
#define pf printf
#define Pi 2*acos(0.0)
#define ms(a,b) memset(a, b, sizeof(a))
#define pb(a) push_back(a)
#define MP make_pair
#define db double
#define ll long long
#define EPS 10E-10
#define ff first
#define ss second
#define sqr(x) (x)*(x)
#define D(x) cerr<<#x " = "<<(x)<<endl
#define VI vector <int>
#define DBG pf("Hi\n")
#define MOD 1000000007
#define CIN ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define SZ(a) (int)a.size()
#define sf(a) scanf("%d",&a)
#define sfl(a) scanf("%lld",&a)
#define sff(a,b) scanf("%d %d",&a,&b)
#define sffl(a,b) scanf("%lld %lld",&a,&b)
#define sfff(a,b,c) scanf("%d %d %d",&a,&b,&c)
#define sfffl(a,b,c) scanf("%lld %lld %lld",&a,&b,&c)
#define stlloop(v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define loop(i,n) for(int i=0;i<n;i++)
#define loop1(i,n) for(int i=1;i<=n;i++)
#define REP(i,a,b) for(int i=a;i<b;i++)
#define RREP(i,a,b) for(int i=a;i>=b;i--)
#define TEST_CASE(t) for(int z=1;z<=t;z++)
#define PRINT_CASE printf("Case %d: ",z)
#define LINE_PRINT_CASE printf("Case %d:\n",z)
#define CASE_PRINT cout<<"Case "<<z<<": "
#define all(a) a.begin(),a.end()
#define intlim 2147483648
#define infinity (1<<28)
#define ull unsigned long long
#define gcd(a, b) __gcd(a, b)
#define lcm(a, b) ((a)*((b)/gcd(a,b)))
using namespace std;
//using namespace __gnu_pbds;
//typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
/*----------------------Graph Moves----------------*/
//const int fx[]={+1,-1,+0,+0};
//const int fy[]={+0,+0,+1,-1};
//const int fx[]={+0,+0,+1,-1,-1,+1,-1,+1}; // Kings Move
//const int fy[]={-1,+1,+0,+0,+1,+1,-1,-1}; // Kings Move
//const int fx[]={-2, -2, -1, -1, 1, 1, 2, 2}; // Knights Move
//const int fy[]={-1, 1, -2, 2, -2, 2, -1, 1}; // Knights Move
/*------------------------------------------------*/
/*-----------------------Bitmask------------------*/
//int Set(int N,int pos){return N=N | (1<<pos);}
//int reset(int N,int pos){return N= N & ~(1<<pos);}
//bool check(int N,int pos){return (bool)(N & (1<<pos));}
/*------------------------------------------------*/
#define mx 200005
#define segment_tree int l=n*2,r=l+1,mid=(b+e)/2
pii info[mx];
vector<int>g[mx];
int cnt=0;
int maps[mx],ara[mx];
void dfs(int u, int par)
{
info[u].ff=++cnt;
maps[cnt]=u;
for(int i=0;i<SZ(g[u]);i++)
{
int v=g[u][i];
if(v==par) continue;
dfs(v,u);
}
info[u].ss=cnt;
}
struct data
{
int val, prop;
};
data tree[3*mx];
void push_down(int n, int b, int e)
{
if(tree[n].prop%2)
{
segment_tree;
tree[l].val=(mid-b+1)-tree[l].val;
tree[l].prop++;
tree[r].val=(e-mid)-tree[r].val;
tree[r].prop++;
tree[n].prop=0;
}
}
void init(int n, int b, int e)
{
if(b==e)
{
tree[n].val=ara[maps[b]];
tree[n].prop=0;
return;
}
segment_tree;
init(l,b,mid);
init(r,mid+1,e);
tree[n].val=tree[l].val+tree[r].val;
}
void update(int n, int b, int e, int i, int j)
{
if(b>j || e<i) return;
if(b>=i && e<=j)
{
tree[n].val=(e-b+1)-tree[n].val;
tree[n].prop++;
return;
}
push_down(n,b,e);
segment_tree;
update(l,b,mid,i,j);
update(r,mid+1,e,i,j);
tree[n].val=tree[l].val+tree[r].val;
}
int query(int n, int b, int e, int i, int j)
{
if(b>j || e<i) return 0;
if(b>=i && e<=j) return tree[n].val;
push_down(n,b,e);
segment_tree;
int p=query(l,b,mid,i,j);
int q=query(r,mid+1,e,i,j);
return p+q;
}
char str[10];
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n;
sf(n);
for(int i=2;i<=n;i++)
{
int a;
sf(a);
g[a].pb(i);
}
for(int i=1;i<=n;i++) sf(ara[i]);
dfs(1,1);
init(1,1,n);
int q;
sf(q);
while(q--)
{
int a;
scanf(" %s %d",str,&a);
if(str[0]=='g')
{
int x=query(1,1,n,info[a].ff,info[a].ss);
printf("%d\n",x);
}
else
{
update(1,1,n,info[a].ff,info[a].ss);
}
}
return 0;
}