hdu 4810 Wall Painting

先将每个数字  转成二进制;  然后统计每一位在N个数字中有多少个 1  然后知道 组合中 1 的个数为奇数个时需要加上(i<<i); 然后就是简单的模拟了

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<cmath>
#define mod 1000003
using namespace std;

int N; __int64 arr[1123],num[1123],res[1123],pre[1123][1123];
int main( )
{
    for( int i = 0; i < 1123; i++ )
    {
        pre[i][0] = 1;
        for( int j = 1; j <= i; j++  )
        pre[i][j] = (pre[i-1][j-1]+pre[i-1][j])%mod;
    }
    while( scanf("%d",&N) != EOF )
    {
        memset( num,0,sizeof(num) );
        memset( res,0,sizeof(res) );
        for( int i = 1; i <= N; i++ )
          scanf("%I64d",&arr[i]);
        for( int i = 0; i <= 30; i++ )
        for( int j = 1; j <=  N; j++ ){
            if( (arr[j]&(1<<i)) != 0 )num[i]++;
        }
        for( int i = 0; i <= 30; i++ )
        for( int j = 1; j <=  N; j++ )
        {
           __int64 a = N - num[i]; if( num[i] == 0 )continue;
           for( int k = 1; k <= num[i]; k += 2 )
           {
               if( j - k <= a )res[j] += (((pre[num[i]][k]*pre[a][j-k])%mod)*(1<<i))%mod;
               res[j] %=mod;
           }
        }
        printf("%I64d",res[1]);
        for( int i = 2; i <= N; i++ )
        printf(" %I64d",res[i]);
        cout<<endl;
    }
    return 0;
}

  

posted on 2013-12-01 15:07  浪舟  阅读(404)  评论(0编辑  收藏  举报

导航