1. 程式人生 > >XOR and Favorite Number CodeForces - 617E -莫隊-異或前綴和

XOR and Favorite Number CodeForces - 617E -莫隊-異或前綴和

per col pac scan pre turn spa del %d

CodeForces - 617E

給n個數, m個詢問, 每次詢問問你[l, r]區間內有多少對(i, j), 使得a[i]^a[i+1]^......^a[j]結果為k。(註意 i ! = j)
維護一個前綴異或值就可以了。要註意的是 區間[l, r], 我們需要將pre[l-1]......pre[r]都加進去, pre[l-1]不能少。

#include<bits/stdc++.h>
using namespace std;
#define maxn 1234567
#define ll long long
ll s[1<<22],n,m,k,col[maxn],B,sum,ans[maxn],pre[maxn],l,r;
struct node
{
    int l,r,id;
    bool operator<(const node &b)const
    {
        return l/B==b.l/B?r<b.r:l<b.l;
    }
} a[maxn];
void del(int x)
{
    s[pre[x]]--;
    sum-=s[k^pre[x]];
}
void add(int x)
{
    sum+=s[k^pre[x]];
    s[pre[x]]++;
}
int main()
{
    r=-1;
    scanf("%lld%lld%lld",&n,&m,&k);
    for(int i=1; i<=n; i++)
    {
        scanf("%lld",&col[i]);
        pre[i]=pre[i-1]^col[i];
    }
    B=sqrt(n);
    for(int i=0; i<m; i++)
    {
        scanf("%d%d",&a[i].l,&a[i].r);
        a[i].id=i;
        a[i].l--;
    }
    sort(a,a+m);
    for(int i=0; i<m; i++)
    {
        while(l<a[i].l)
            del(l++);
        while(r>a[i].r)
            del(r--);
        while(l>a[i].l)
            add(--l);
        while(r<a[i].r)
            add(++r);
        ans[a[i].id]=sum;
    }
    for(int i=0; i<m; i++)printf("%lld\n",ans[i]);
    return 0;
}

  

XOR and Favorite Number CodeForces - 617E -莫隊-異或前綴和