[CQOI 2018]异或序列&[Codeforces 617E]XOR and Favorite Number

本文介绍了一种使用莫队算法解决区间异或和查询问题的方法。对于给定的整数序列,通过预处理和巧妙的数据结构优化,快速计算任意指定区间内所有连续子序列的异或和等于特定值的数量。

Description

题库链接1 题库链接2

已知一个长度为 \(n\) 的整数数列 \(a_1,a_2,\cdots,a_n\) ,给定查询参数 \(l,r\) ,问在 \([l,r]\) 区间内,有多少连续子序列满足异或和等于 \(k\)

CQOI 数据范围: \(1\leq n\leq 10^5, a_i,k\leq 10^5\)

CF 数据范围: \(1\leq n\leq 10^5, a_i,k\leq 10^6\)

Solution

撞题也是醉了...

莫队傻逼题,乱搞即可。

Code

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+5, SIZE = 1<<20;

int n, m, k, lim, a[N], cnt[SIZE]; ll ans[N];
struct tt {
    int l, r, id;
    bool operator < (const tt &b) const {
        return l/lim == b.l/lim ? r < b.r : l < b.l;
    }
}b[N];

void work() {
    scanf("%d%d%d", &n, &m, &k); lim = sqrt(n);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]), a[i] ^= a[i-1];
    for (int i = 1; i <= m; i++) scanf("%d%d", &b[i].l, &b[i].r), --b[i].l, b[i].id = i;
    sort(b+1, b+m+1);
    int curl = 1, curr = 0; ll sum = 0;
    for (int i = 1; i <= m; i++) {
        int l = b[i].l, r = b[i].r;
        while (curr < r) sum += cnt[a[++curr]^k], ++cnt[a[curr]];
        while (curl > l) sum += cnt[a[--curl]^k], ++cnt[a[curl]];
        while (curr > r) --cnt[a[curr]], sum -= cnt[a[curr--]^k];
        while (curl < l) --cnt[a[curl]], sum -= cnt[a[curl++]^k];
        ans[b[i].id] = sum;
    }
    for (int i = 1; i <= m; i++) printf("%lld\n", ans[i]);
}
int main() {work(); return 0; }

转载于:https://www.cnblogs.com/NaVi-Awson/p/8984004.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值