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;
    }
    
  • 相关阅读:
    linux 安全组
    php 类
    linux安装phpmyadmin
    mysql设置对外访问
    linux 防火墙
    微信小程序之swiper组件高度自适应
    Thinkphp5 关联模型
    README.md文件编辑
    linux安装mysql
    小程序返回顶部top滚动
  • 原文地址:https://www.cnblogs.com/ftae/p/7764613.html
Copyright © 2011-2022 走看看