Title address
Title: Give you a tree, 1 is the root node, each node should be state 0 or 1, you have two operations, the operation of pow is that the node and all its sub-trees each node for its own exclusive or operation, get is to query the node and all its sub-trees each node how many 1.
Idea: We first search all the subtrees through dfs and mark them well. Then we update the line segment tree through the scope of the subtree given. Then we update and query the line segment tree according to the scope of the subtree obtained before. The line segment tree is a simple interval update + delayed update.
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <cstdio>
#include <algorithm>
#define N 200010
#define LL __int64
#define inf 0x3f3f3f3f
#define lson l,mid,ans<<1
#define rson mid+1,r,ans<<1|1
#define getMid (l+r)>>1
#define movel ans<<1
#define mover ans<<1|1
using namespace std;
const LL mod = 1e9 + 7;
const double eps = 1e-9;
struct node {
LL sum;
int lazy;
int l, r;
}sum[N << 2];//Line Segment Tree Subject
int num[N], pos[N], len[N], pre[N], cnt;
vector<int> v[N];
struct Segment__Tree {
int x, y;
void pushUp(int ans) {
sum[ans].sum = sum[movel].sum + sum[mover].sum;
}
void pushDown(int ans) {
if (sum[ans].lazy) {
sum[movel].lazy ^= 1;
sum[mover].lazy ^= 1;
sum[movel].sum = sum[movel].r - sum[movel].l + 1 - sum[movel].sum;
sum[mover].sum = sum[mover].r - sum[mover].l + 1 - sum[mover].sum;
sum[ans].lazy = 0;
}
}
void build(int l, int r, int ans) {
sum[ans].l = l;
sum[ans].r = r;
sum[ans].lazy = 0;
if (l == r) {
sum[ans].sum = num[pre[l]];
return;
}
int mid = getMid;
build(lson);
build(rson);
pushUp(ans);
}
LL solve(int l, int r, int ans) {
if (l >= x&&r <= y) {
return sum[ans].sum;
}
pushDown(ans);
int mid = getMid;
if (mid<x) {
return solve(rson);
}
else if (mid >= y) {
return solve(lson);
}
else {
return solve(lson) + solve(rson);
}
}
void updata(int l, int r, int ans) {
if (l >= x&&r <= y) {
sum[ans].sum = r - l + 1 - sum[ans].sum;
sum[ans].lazy ^= 1;
return;
}
pushDown(ans);
int mid = getMid;
if (mid<x) {
updata(rson);
}
else if (mid >= y) {
updata(lson);
}
else {
updata(lson);
updata(rson);
}
pushUp(ans);
}
}tree;
void init(int n) {
for (int i = 0; i <= n; i++) {
v[i].clear();
}
}
void dfs(int u) {
int lens = v[u].size();
for (int i = 0; i < lens; i++) {
int vv = v[u][i];
pos[vv] = ++cnt;//Starting Point of Subtree
pre[cnt] = vv;
dfs(vv);
len[vv] = cnt;//The End of Subtree
}
}
int main() {
cin.sync_with_stdio(false);
int n, x, q;
string str;
while (cin >> n) {
init(n);
for (int i = 2; i <= n; i++) {
cin >> x;
v[x].push_back(i);
}
for (int i = 1; i <= n; i++) {
cin >> num[i];
}
cin >> q;
cnt = 0;
pos[1] = ++cnt;
pre[cnt] = 1;
len[1] = n;
dfs(1);
tree.build(1, n, 1);
while (q--) {
cin >> str;
if (str[0] == 'g') {
cin >> x;
tree.x = pos[x];
tree.y = len[x];
cout << tree.solve(1, n, 1) << endl;
}
else {
cin >> x;
tree.x = pos[x];
tree.y = len[x];
tree.updata(1, n, 1);
}
}
}
return 0;
}