zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Xcode8 1 创建coreData的ManagedObject后,报错 linker command failed with exit code 1
    在IOS中根据圆心坐标、半径和角度计算圆弧上的点坐标
    NodeJS学习目录
    nodeJS之URL
    nodeJS之域名DNS
    初识nodeJS
    使用nodeJS实现前端项目自动化之项目构建和文件合并
    nodeJS之fs文件系统
    nodeJS之二进制buffer对象
    nodeJS之进程process对象
  • 原文地址:https://www.cnblogs.com/ftae/p/7764613.html
Copyright © 2011-2022 走看看