CodeForces - 703D Mishka and Interesting sum(线段树离线)

题目链接

题目大意

  询问区间出现次数为偶数的数的异或和。

解题思路

  求所有数的前缀异或和,再用线段树离线求出所有询问区间的不同数的异或和。

int n, m, a[maxn];
int sum[maxn];
vector<P> q[maxn];
int tr[maxn<<2], ans[maxn];
map<int, int> lst;
void update(int rt, int l, int r, int p, int v) {
    if (l==r) {
        tr[rt] ^= v;
        return;
    }
    int mid = (l+r)>>1;
    if (p<=mid) update(rt<<1, l, mid, p, v);
    else update(rt<<1|1, mid+1, r, p, v);
    tr[rt] = tr[rt<<1]^tr[rt<<1|1];
}
int ask(int rt, int l, int r, int L, int R) {
    if (l>=L && r<=R) return tr[rt];
    int mid = (l+r)>>1;
    int sum = 0;
    if (L<=mid) sum ^= ask(rt<<1, l, mid, L, R);
    if (R>mid) sum ^= ask(rt<<1|1, mid+1, r, L, R);
    return sum;
}
int main() {
    IOS;
    cin >> n;
    for (int i = 1; i<=n; ++i) cin >> a[i], sum[i] = sum[i-1]^a[i];
    cin >> m;
    for (int i = 1; i<=m; ++i) {
        int l, r; cin >> l >> r;
        q[r].push_back({l, i});
    }
    for (int i = 1; i<=n; ++i) {
        if (lst[a[i]]) update(1, 1, n, lst[a[i]], a[i]);
        lst[a[i]] = i;
        update(1, 1, n, i, a[i]);
        for (auto v : q[i]) {
            int res = ask(1, 1, n, v.x, i);
            ans[v.y] = res^sum[i]^sum[v.x-1];
        }
    }
    for (int i = 1; i<=m; ++i) cout << ans[i] << endl;
    return 0;
}
posted @ 2021-07-29 21:13  shuitiangong  阅读(37)  评论(0编辑  收藏  举报