题意:就是在n个数里,取1个异或起来的所有情况加起来,取2个值异或起来的所有值加起来,一直到取n个值异或的情况加起来,输出1-n的所有答案。。
把每个数都用2进制表示出来,然后统计每个数位上1的个数,然后就是取k个数在上面异或,所以有奇数个1异或起来就是1,偶数个就是0,组合数算下就好。
/*************************************************************************
> File Name: 4810.cpp
> Author: tjw
> Mail:
> Created Time: 2014年11月09日 星期日 16时14分49秒
************************************************************************/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#define ll long long
#define ls k<<1
#define rs k<<1|1
using namespace std;
const int MAXN=32;
const int MOD=1000003;
int a[32],b[32];
long long c[1010][1010];
int top;
void doit(int x)
{
int k=0;
while(x)
{
a[k++]+=x%2;
x>>=1;
}
if(k>top)
top=k;
}
int main()
{
int i,j,n,x,k;
memset(c,0,sizeof(c));
c[0][0]=1;
for(i=1;i<=1000;i++)
{
c[i][0]=1;
for(j=1;j<=i;j++)
{
c[i][j]=(c[i-1][j-1]+c[i-1][j])%MOD;
}
}
while(scanf("%d",&n)==1)
{
memset(a,0,sizeof(a));
top=0;
for(i=0;i<n;i++)
{
scanf("%d",&x);
doit(x);
}
for(i=0;i<top;i++)
b[i]=n-a[i];
for(i=1;i<=n;i++)
{
int ans=0;
for(j=0;j<top;j++)
{
for(k=1;k<=i;k+=2)
{
int zero=i-k;
if(k>a[j])
break;
if(zero>b[j])
continue;
ll temp=(c[a[j]][k]*c[b[j]][zero])%MOD;
int temp1=(temp<<j)%MOD; //temp要是64位的才不会爆。。。。
ans=(ans+temp1)%MOD;
}
}
if(i<n)
printf("%d ",ans);
else
printf("%d\n",ans);
}
}
return 0;
}
本文探讨了在特定数值集合中,通过异或运算进行组合的数学原理及应用,详细解释了如何利用组合数学计算不同数量元素异或后的所有可能结果。
3981

被折叠的 条评论
为什么被折叠?



