拖了这么多天,终于把这个题过了。
题意:一棵有根树, 每个节点可以是1或者0, 两种操作:
1. pow v: 将v节点的子树中所有节点的值反置(1变0, 0变1, 相当于异或1)
2. get v: 输出v节点的字数中1的个数
DFS序+线段树
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<sstream>
#include<cstdlib>
#include<time.h>
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define repp(i,n,a) for(int i=n;i>=a;i--)
#define ll long long
#define ull unsigned long long
#define mem(a,x) memset((a),(x),sizeof ((a)))//x只能是0或-1或false或true
#define debug(x) cout<<"X: "<<(x)<<endl
#define de cout<<"************"<<endl
#define lowbit(x) ((x)&(-x))
#define lson rt<<1
#define rson rt<<1|1
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a*b/(__gcd(a,b))
#define inf 0x3f3f3f3f//1e9+6e7
#define Eps 1e-8
#define Mod 1e9+7
#define maxn 100010
const double pi=acos(-1.0);
using namespace std;
vector<int> v[200010];
int a[200010],b[200010];
struct tree{
int l,r;
int sum,add;
}t[200010*4];
int cnt=1;
int son[200010];
void dfs(int x)
{
a[x]=cnt;
int m=cnt;
cnt++;
if(v[x].size()==0)
{
son[m]=0;
return ;
}
for(int i=0;i<v[x].size();i++)
{
dfs(v[x][i]);
son[m]+=(son[a[v[x][i]]]+1);
}
return ;
}
void build(int p,int l,int r)
{
t[p].l=l;
t[p].r=r;
if(l==r)
{t[p].sum=b[l];return ;}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
}
void spread(int p)
{
if(t[p].add)
{
t[p<<1].sum=t[p<<1].r-t[p<<1].l+1-t[p<<1].sum;
t[p<<1|1].sum=t[p<<1|1].r-t[p<<1|1].l+1-t[p<<1|1].sum;
t[p<<1].add=1-t[p<<1].add;
t[p<<1|1].add=1-t[p<<1|1].add;
t[p].add=0;
}
}
void change(int p,int l,int r,int d)
{
if(l<=t[p].l&&t[p].r<=r)
{
t[p].sum=t[p].r-t[p].l+1-t[p].sum;
t[p].add=1-t[p].add;
return ;
}
spread(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid)
change(p<<1,l,r,d);
if(mid<r)
change(p<<1|1,l,r,d);
t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
}
int ask(int p,int l,int r)
{
if(l<=t[p].l&&t[p].r<=r)
return t[p].sum;
spread(p);
int mid=(t[p].l+t[p].r)>>1;
int ret=0;
if(l<=mid)
ret+=ask(p<<1,l,r);
if(mid<r)
ret+=ask(p<<1|1,l,r);
return ret;
}
int main()
{
int n;
cin>>n;
int x;
rep(i,2,n)
{
scanf("%d",&x);
v[x].push_back(i);
}
dfs(1);
rep(i,1,n)
{
scanf("%d",&x);
b[a[i]]=x;
}
build(1,1,n);
int q;
cin>>q;
char s[5];
while(q--)
{
getchar();
scanf("%s%d",s,&x);
if(s[0]=='g')
printf("%d\n",ask(1,a[x],a[x]+son[a[x]]));
else
change(1,a[x],a[x]+son[a[x]],1);
}
return 0;
}