题意:给n(n<=1000)个数,求从中取k个数亦或的所有结果的和。
解题思路:把n个数都转成二进制统计每位上1的个数,然后就会发现如果选择k个数,有奇数个1,亦或结果就是1,这样就用组合数算一下就可以了。
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const long long mod=1000003;
long long sum[100];
long long c[1100][1100];
void pre()
{
for (int i=0;i<=1010;i++)
{
c[i][0]=1;
c[i][i]=1;
}
for (int i=1;i<=1010;i++)
for (int j=1;j<=i;j++)
{
c[i][j]=c[i-1][j]+c[i-1][j-1];
c[i][j]%=mod;
}
}
void add(long long num)
{
int sn=0;
while (num>0)
{
if (num%2)
sum[sn]++;
sn++;
num/=2;
}
}
int main()
{
// freopen("in.txt","r",stdin);
pre();
int n;
long long num;
while (~scanf("%d",&n))
{
memset(sum,0,sizeof(sum));
for (int i=1;i<=n;i++)
{
scanf("%I64d",&num);
add(num);
}
for (int k=1;k<=n;k++)
{
long long ans=0;
for (int i=0;i<65;i++)
{
long long s=0;
for (int x=1;x<=sum[i];x+=2)
{
if (k-x>=0&&n-sum[i]>=k-x)
{
s+=c[n-sum[i]][k-x]*c[sum[i]][x];
s%=mod;
}
}
ans+=s*(1<<i);
ans%=mod;
}
if (k<n)
printf("%I64d ",ans);
else
printf("%I64d\n",ans);
}
}
return 0;
}