• P2574 XOR的艺术


    线段树

    题意:

    给定一个01串

    要求支持两种操作:

    1 - 区间 xor

    2 - 区间求和

    做法:

    普通的线段树的求和

    用 rev 表示该区间是否被 xor

    因为 xor 两次就相当于没有 xor

    所以当区间 xor 的时候

    对 rev 取反, sum = 区间长度 - sum

    code:

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2 * 100005;
    int a[N], n, m, opt, L, R;
    struct Stree {
        int l, r, sum; bool rev;
    }tree[N * 3];
    
    template <typename T>
    inline void read(T &t) {
        t = 0; T m = 1; char ch = getchar(); 
        while(ch < '0' || ch > '9') { if(ch == '-') m = -1; ch = getchar(); }
        while(ch >= '0' && ch <= '9') { t = (t << 3) + (t << 1) + (ch & 15); ch = getchar(); }
        t *= m;
    } 
    
    void pushup(int rt) {
        tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
    }
    
    void pushdown(int rt) {
        if(tree[rt].rev) {
            tree[rt << 1].rev = !tree[rt << 1].rev, tree[rt << 1 | 1].rev = !tree[rt << 1 | 1].rev;
            tree[rt << 1].sum = (tree[rt << 1].r - tree[rt << 1].l + 1 - tree[rt << 1].sum);
            tree[rt << 1 | 1].sum = (tree[rt << 1 | 1].r - tree[rt << 1 | 1].l + 1 - tree[rt << 1 | 1].sum);
            tree[rt].rev = 0;
        }
    }
    
    void build(int l, int r, int rt) {
        tree[rt].l = l, tree[rt].r = r, tree[rt].sum = 0, tree[rt].rev = 0;
        if(l == r) {
            tree[rt].sum = a[l]; return;
        }
        int mid = (l + r) >> 1;
        build(l, mid, rt << 1), build(mid + 1, r, rt << 1 | 1);
        pushup(rt);
    }
    
    int Quary(int L, int R, int l, int r, int rt) {
        if(L <= l && r <= R) return tree[rt].sum;
        pushdown(rt);
        int mid = (l + r) >> 1, ans = 0;
        if(L <= mid) ans += Quary(L, R, l, mid, rt << 1);
        if(R > mid) ans += Quary(L, R, mid + 1, r, rt << 1 | 1);
        return ans;
    }
    
    void upd(int L, int R, int l, int r, int rt) {
        if(L <= l && r <= R) {
            tree[rt].rev = !tree[rt].rev;
            tree[rt].sum = (r - l + 1 - tree[rt].sum);
            return;
        }
        pushdown(rt);
        int mid = (l + r) >> 1;
        if(L <= mid) upd(L, R, l, mid, rt << 1);
        if(R > mid) upd(L, R, mid + 1, r, rt << 1 | 1);
        pushup(rt);
    }
    
    int main() {
        read(n), read(m);
        for(int i = 1; i <= n; i++) {
            scanf("%1d", &a[i]);
        }
        /*r(int i = 1; i <= n; i++) {
            printf("%d%c", a[i], i == n ? '
    ' : ' ');
        }*/
        build(1, n, 1);
        for(int i = 1; i <= m; i++) {
            read(opt), read(L), read(R);
            if(opt == 0) {
                upd(L, R, 1, n, 1);
            } else {
                printf("%d
    ", Quary(L, R, 1, n, 1));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    STL hash_map使用
    STL的 string 类赋值
    STL map使用详解
    下面我使用vector容器为基础来构成一棵树
    MFC中CString.Format的详细用法
    error LNK2001: 无法解析的外部符号 "public: static class stdext::hash_map
    !!! STL的string类如何实现CString的Format功能 这是一个经典问题,记住
    STL map和STL set(转载)
    为什么提示此错误?RunTime Check Failure #2 Stack around the variable 'tch1'was corrupted.
    STL源码剖析
  • 原文地址:https://www.cnblogs.com/chloristendika/p/10119571.html
Copyright © 2020-2023  润新知