洛谷P4462 CQOI2018]异或序列 基础莫队+异或性质
洛谷P4462 CQOI2018]异或序列
标签
- 基础莫队
- 异或
前言
- 有个东西没搞懂,,以后填坑!
简明题意
- 询问区间L,R由多少个子区间(连续)的异或和为k
思路
- 莫队鸭
- 难道在于转移。假设当前区间l,r中,异或和为k的有ans个,然后现在r要右移。
- r右移,r++,相当于要往后面新增一个数。假设现在r已经++了,那么很显然的是[l,r-1]的贡献不会变,新增加的贡献是以r为右端点,[l,r-1]为左端点的这些区间。所以现在ans就应该加上[l,r-1]中,与a[r]异或和起来为k的值。
- 由上,我们需要求一个区间的异或和,那么很自然想到前缀和,我们提前就处理好前缀和,然后转移时就变成求 [l,r-1]有多少个数与a[r]异或和为k,然而前缀和是 sum[r]-sum[l-1],所以应该是求 [l-1,r]有多少个数与a[r]异或和为k。
- 这样的话,我们还是得遍历一遍区间。所以需要优化。关于异或有这样一个性质:a^b=k\(\iff\) a^k=b\(\iff\) b^k=a,所以我们又能换成:[l-1,r]有多少个数异或值为 k^a[r],转换成这样,就能很容易开一个数组记录异或值i出现的次数,然后就很容易转移了
- 但是这题,前缀和是查询l-1开始的,这个看起来比较难处理。实际上这个我也没有搞清楚惹,但是暂时就记住,如果莫队维护的是前缀和的话,那就再读入的时候把l--就行了惹。
注意事项
- 无
总结
- 如果莫队维护的是前缀和的话,那就再读入的时候把l--就行了惹。
- 关于异或的性质:如果又a^b=c,那么任意两个的异或值都等于第三个
AC代码
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 10;
struct Query
{
int l, r, id, k;
bool operator < (const Query& a)const
{
if (k == a.k)
return r < a.r;
return k < a.k;
}
};
Query query[maxn];
int n, q, k, a[maxn];
int ans, cnt[maxn];
void remove(int id)
{
int x = a[id];
ans -= cnt[k ^ x];
cnt[x]--;
}
void add(int id)
{
int x = a[id];
ans += cnt[k ^ x];
cnt[x]++;
}
int ans0[maxn];
void solve()
{
scanf("%d%d%d", &n, &q, &k);
int len = sqrt(n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]), a[i] ^= a[i - 1];
for (int i = 1; i <= q; i++)
scanf("%d%d", &query[i].l, &query[i].r), query[i].l--, query[i].id = i, query[i].k = (query[i].l - 1) / len + 1;
sort(query + 1, query + 1 + q);
int l = 1, r = 0;
for (int i = 1; i <= q; i++)
{
int L = query[i].l, R = query[i].r, id = query[i].id;
while (l < L) remove(l++);
while (l > L) add(--l);
while (r < R) add(++r);
while (r > R) remove(r--);
ans0[id] = ans;
}
for (int i = 1; i <= q; i++)
printf("%d\n", ans0[i]);
}
int main()
{
//freopen("Testin.txt", "r", stdin);
solve();
return 0;
}
作者:danzh
QQ:1244536605
CSDN(和博客园同步):https://blog.csdn.net/weixin_42431507
-----------------------------------------------------------------------------------------------
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其
它人怎么样,我们也能够保持自己的本色走下去。
—clj