Codeforces #442 Div2 E

#442 Div2 E

题意

给你一棵树,每个结点有开关(0表示关闭,1表示开启),两种操作:

  1. 反转一棵子树所有开关
  2. 询问一棵子树有多少开关是开着的

分析

先 DFS 把树上的结点映射到区间上,然后就是线段树区间更新、区间求和了。

code

#include<bits/stdc++.h>
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
typedef long long ll;
using namespace std;
const int MAXN = 2e5 + 10;
int n, cnt, sl[MAXN], sr[MAXN], a[MAXN], b[MAXN];
vector<int> G[MAXN];
void dfs(int u) {
    sl[u] = ++cnt;
    for(int v : G[u]) dfs(v);
    sr[u] = cnt;
}
int s[MAXN << 2], lazy[MAXN << 2];
void pushUp(int rt) {
    s[rt] = s[rt << 1] + s[rt << 1 | 1];
}
void pushDown(int rt, int len) {
    if(lazy[rt]) {
        lazy[rt << 1] ^= 1;
        lazy[rt << 1 | 1] ^= 1;
        s[rt << 1] = len - len / 2 - s[rt << 1];
        s[rt << 1 | 1] = len / 2 - s[rt << 1 | 1];
        lazy[rt] = 0;
    }
}
void build(int l, int r, int rt) {
    if(l == r) {
        s[rt] = b[a[l]];
    } else {
        int m = l + r >> 1;
        build(lson);
        build(rson);
        pushUp(rt);
    }
}
void update(int L, int R, int l, int r, int rt) {
    if(l >= L && r <= R) {
        lazy[rt] ^= 1;
        s[rt] = r - l + 1 - s[rt];
    } else {
        pushDown(rt, r - l + 1);
        int m = l + r >> 1;
        if(m >= L) update(L, R, lson);
        if(m < R) update(L, R, rson);
        pushUp(rt);
    }
}
int query(int L, int R, int l, int r, int rt) {
    if(l >= L && r <= R) return s[rt];
    else {
        pushDown(rt, r - l + 1);
        int m = l + r >> 1;
        int res = 0;
        if(m >= L) res += query(L, R, lson);
        if(m < R) res += query(L, R, rson);
        pushUp(rt);
        return res;
    }
}
int main() {
    scanf("%d", &n);
    for(int i = 2; i <= n; i++) {
        int x;
        scanf("%d", &x);
        G[x].push_back(i);
    }
    dfs(1);
    for(int i = 1; i <= n; i++) scanf("%d", &b[i]);
    for(int i = 1; i <= n; i++) a[sl[i]] = i;
    build(1, n, 1);
    int q;
    scanf("%d", &q);
    while(q--) {
        char c[4];
        int x;
        scanf("%s%d", c, &x);
        if(c[0] == 'g') printf("%d
", query(sl[x], sr[x], 1, n, 1));
        else update(sl[x], sr[x], 1, n, 1);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ftae/p/7764613.html