問題 A: 異或序列

問題 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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章