問題 A: 異或序列
時間限制: 1 Sec 內存限制: 128 MB
提交: 188 解決: 86
[提交] [狀態] [討論版] [命題人:admin]
題目描述
已知一個長度爲n的整數數列a1,a2,…,an,給定查詢參數l、r,問在al,al+1,…,ar區間內,有多少子序列滿足異或和等於k。也就是說,對於所有的x,y(l≤x≤y≤r),滿足ax⊕ax+1⊕⋯⊕ay=k的x,y有多少組。
輸入
輸入第一行爲3個整數n,m,k。第二行爲空格分開的n個整數,即a1,a2,…,an。接下來m行,每行兩個整數lj,rj,代表一次查詢。
輸出
輸出共m行,對應每個查詢的計算結果。
樣例輸入
4 5 1 1 2 3 1 1 4 1 3 2 3 2 4 4 4
樣例輸出
4 2 1 2 1
提示
對於30%的數據,1≤n,m≤1000。
對於100%的數據,1≤n,m≤105,0≤k,ai≤105,1≤lj≤rj≤n。
莫隊板子題,只要維護下前綴和就行,順便學了一波簡單莫隊
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int a[100005],ans[100005];
int tmp[100005];
int l,r,cnt,tmpp;
struct fun
{
int i,l,r;
}z[100005];
bool cmp (fun a, fun b)
{
if (a.l / tmpp != b.l / tmpp)
return a.l < b.l;
return a.r < b.r;
}
bool cmp1(fun a, fun b)
{
return a.i < b.i;
}
int main()
{
// freopen("in.txt", "r", stdin);
int n,m,k;
scanf("%d%d%d", &n, &m, &k);
tmpp = (int)sqrt(n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 2; i <= n; i++)
a[i] ^= a[i - 1];
for (int i = 0; i < m; i++)
{
z[i].i = i;
scanf("%d%d", &z[i].l, &z[i].r);
z[i].l--;
}
tmp[ a[0] ]++;
sort(z, z + m, cmp);
for (int i = 0; i < m; i++)
{
while (l < z[i].l)
{
cnt -= tmp[a[l] ^ k];
tmp[ a[l] ]--;
l++;
}
while (l > z[i].l)
{
l--;
cnt += tmp[a[l] ^ k];
tmp[ a[l] ]++;
}
while (r < z[i].r)
{
r++;
cnt += tmp[a[r] ^ k];
tmp[ a[r] ]++;
}
while (r > z[i].r)
{
cnt -= tmp[a[r] ^ k];
tmp[ a[r] ]--;
r--;
}
ans[ z[i].i ] = cnt;
}
sort(z, z + n, cmp1);
for (int i = 0; i < m; i++)
printf("%d\n", ans[i]);
return 0;
}