Excludsive OR(容斥/计数)

题意:给定n个两两不同的正整数 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n 和两个整数,对于 [ L , R ] [L,R] 上每个整数x,输出符合ai^aj^ak==x(i<j<k)的三元组(i,j,k)的数量。
1 < = n < = 5000 , 1 < = a i < = 5000 , 1 < = L < = R < = 10000 1<=n<=5000,1<=a_i<=5000,1<=L<=R<=10000
代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1<<13;

int cnt1[maxn];//记录由一个数组成i的个数cnt1[i]
int cnt2[maxn];//记录由两个数异或组成i的个数cnt2[i]
int cnt3[maxn];//记录由三个数异或组成的个数cnt3[i]
int a[3010];
int n,L,R;
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        cnt1[a[i]]=1;
    }
    scanf("%d%d",&L,&R);
    for(int i=0;i<n;i++)
        for(int j=0;j<maxn;j++)
            cnt2[a[i]^j]+=cnt1[j];// 对于x=a[i]^j number(x) += number(a[i])*number(j) 这里number(a[i])==1
    for(int i=0;i<n;i++)
        for(int j=0;j<maxn;j++)
            cnt3[a[i]^j]+=cnt2[j];// 对于x=a[i]^j number(x) += number(a[i])*number(j) 这里number(a[i])==1,j是由2个数异或得到的
    for(int i=L;i<=R;i++)
        //这里的3*n是怎么来的 就是对于当前i 它和另外两个相同的数k组成 (1<=k<=n),k有n种选择,
        //且有(i,k,k) (k,i,k) (k,k,i)这3种组合,同时(i,i,i)本身只算一种,所以共3*n-2种不合法的
        if(i<maxn) printf("%d\n",(cnt3[i]-cnt1[i]*(3*n-2))/6);
        else printf("0\n");
}

发布了71 篇原创文章 · 获赞 1 · 访问量 2826

猜你喜欢

转载自blog.csdn.net/weixin_43918473/article/details/103038965