QUERIES

 

 

 

 

 

 这个题解。。
u1s1我没看懂,但是我觉得这里面有一个重要的思想就是对于像异或这种最终值只是看一个数位的问题,我们可以考虑分解,把每一个子问题单独解决就可以了
其实更难的应该是每个子区间的异或和之和这个方面。。

这里放上dalao的代码

#include<bits/stdc++.h>
using namespace std;
const int N = 100009, M = 400009, Mod = 4001;
int n, m, a[N]; 
struct tree{int l0, l1, r0, r1, sum, val0, val1;} t[M][11];
tree merge(tree x, tree y) {
    tree tmp = {};
    tmp.val0 = x.val0 + y.val0 + x.r0 * y.l0 % Mod + x.r1 * y.l1 % Mod;
    tmp.val1 = x.val1 + y.val1 + x.r0 * y.l1 % Mod + x.r1 * y.l0 % Mod;
    if (x.sum == 0) tmp.l0 = x.l0 + y.l0, tmp.l1 = x.l1 + y.l1;
    else tmp.l0 = x.l0 + y.l1, tmp.l1 = x.l1 + y.l0;
    if (y.sum == 0) tmp.r0 = y.r0 + x.r0, tmp.r1 = y.r1 + x.r1;
    else tmp.r0 = y.r0 + x.r1, tmp.r1 = y.r1 + x.r0;
    tmp.val0 %= Mod, tmp.val1 %= Mod, tmp.l0 %= Mod, tmp.l1 %= Mod, tmp.r0 %= 
Mod, tmp.r1 %= Mod, tmp.sum = x.sum ^ y.sum;
    return tmp;
}
void change(int p, int l, int r, int k, int u, int v) {
    if (l > u || r < u) return ;
    if (l == r && l == u) {
        if (v == 0) t[p][k].l0 = t[p][k].r0 = t[p][k].val0 = 1, t[p][k].l1 = 
t[p][k].r1 = t[p][k].val1 = 0;
        else t[p][k].l0 = t[p][k].r0 = t[p][k].val0 = 0, t[p][k].l1 = t[p][k].r1 
= t[p][k].val1 = 1;
        t[p][k].sum = v;
        return ;
    }
    int mid = l + r >> 1;
    change(p << 1, l, mid, k, u, v);
    change(p << 1 | 1, mid + 1, r, k, u, v);
    t[p][k] = merge(t[p << 1][k], t[p << 1 | 1][k]);
}
tree ask(int p, int l, int r, int k, int x, int y) {
    if (y < l || x > r) return t[0][0];
    if (x <= l && r <= y) return t[p][k];
    int mid = l + r >> 1;    return merge(ask(p << 1, l, mid, k, x, y), ask(p << 1 | 1, mid + 1, r, k, x, 
y));
}
int power(int a, int b) {int res = 1; for (; b; b >>= 1, a = 1LL * a * a % Mod) 
if (b & 1) res = 1LL * res * a % Mod; return res;}
int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++ i) {
        int x;
        scanf("%d", &x);
        for (int j = 1; j <= 10; ++ j) change(1, 1, n, j, i, x & (1 << j - 1));
    }
    while(m --) {
        int op, x, y;
        scanf("%d%d%d", &op, &x, &y);
        if (op == 1) for (int i = 1; i <= 10; ++ i) change(1, 1, n, i, x, y & (1 
<< i - 1));
        else {
            int res = 0;
            for (int i = 1; i <= 10; ++ i) res = (res + 1LL * ask(1, 1, n, i, x, 
y).val1 * power(2, i - 1) % Mod) % Mod;
            printf("%d\n", res);
        }
    }
    return 0;
}

 

posted @ 2020-09-11 20:18  HL_ZZP  阅读(372)  评论(0编辑  收藏  举报