Codeforces 877 E Danil and a Part-time Job (Segment Tree + dfs Order)

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;
}

Posted by php4hosting on Fri, 08 Feb 2019 11:12:17 -0800