原本我想当标题党的,但事实上是WAon#1求调
查看原帖
原本我想当标题党的,但事实上是WAon#1求调
1010254
Myano楼主2023/6/24 08:27

思路是分块,记一个前缀和和连续块答案,然后统计贡献。

#1 错在了第四次询问:

50 1275 3
5 7 4 5 6 8 0 6 4 6 7 2 2 3 0 5 5 6 5 4 7 2 0 1 3 5 3 4 7 8 2 3 2 7 6 6 2 0 8 3 6 1 8 4 3 1 5 6 4 1
38 39
29 30
7 36
26 43
30 35
1 25
15 30
18 22
24 32
5 34
3 23
11 19
25 30
12 30
33 37
12 48
10 12
23 28
12 21
9 44
11 11
36 50
22 43
36 44
11 32
17 21
33 36
31 36
5 44
……
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=1e3+10,M=4e2+10;
int n,m,K,len,cnt,Max;
int a[N],p[N][M],f[M][M],val[M][N],st[M],ed[M],bar[N];
void init(){
    int w[N*2]={};
    scanf("%d%d%d",&n,&m,&K);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]),a[i]^=a[i-1],Max=max(Max,a[i]);
    len=sqrt(n);cnt=n/len+bool(n%len);ed[0]=-1;
    for(int i=1;i<=cnt;i++){
        for(int j=0;j<=Max;j++)p[j][i]=p[j][i-1];
        st[i]=ed[i-1]+1;ed[i]=min(i*len,n);
        for(int j=st[i];j<=ed[i];j++)p[a[j]][i]++,bar[j]=i;
    }
    for(int i=1;i<=cnt;i++){
        memset(w,0,sizeof(w));w[0]=(i==1);
        for(int j=i;j<=cnt;j++){
            f[i][j]=f[i][j-1];
            for(int k=st[j];k<=ed[j];k++)f[i][j]+=w[K^a[k]],w[a[k]]++;
        }
    }
    for(int i=1;i<=cnt;i++){
        for(int j=st[i];j<=ed[i];j++)w[j]=a[j];
        sort(w+st[i],w+ed[i]+1);
        for(int j=1;j<=Max;j++)val[i][j]=5e2+1;
        val[i][w[st[i]]]=1;
        for(int j=st[i]+1;j<=ed[i];j++)if(w[j]!=w[j-1])val[i][w[j]]=val[i][w[j-1]]+1;
    }
    return;
}
LL query(int x,int y){
    int l=bar[--x],r=bar[y],w[M]={};LL ret=f[l+1][r-1];
    if(l==r){
        for(int i=x;i<=y;i++)
            ret+=w[val[l][K^a[i]]],w[val[l][a[i]]]++;
        return ret;
    }
    for(int i=x;i<=ed[l];i++)
        ret+=w[val[l][K^a[i]]],w[val[l][a[i]]]++;
    for(int i=st[r];i<=y;i++)
        ret+=w[val[l][K^a[i]]],w[val[l][a[i]]]++;
    for(int i=x;i<=ed[l];i++)ret+=p[K^a[i]][r-1]-p[K^a[i]][l];
    for(int i=st[r];i<=y;i++)ret+=p[K^a[i]][r-1]-p[K^a[i]][l];
    return ret;
}
signed main(){
    init();
    // for(int i=1;i<=n;i++)printf("%d ",a[i]);puts("");
    // for(int i=1;i<=cnt;i++)
    //     {for(int j=st[i];j<=ed[i];j++)printf("%d ",val[i][a[j]]);printf("|");}puts("");
    for(int i=1;i<=m;i++){
        int L,R;
        scanf("%d%d",&L,&R);
        printf("%lld\n",query(L,R));
    }
    system("pause");
    return 0;
}
2023/6/24 08:27
加载中...