hdu-4810 Wall Painting 2013ACM/ICPC亚洲区南京站现场赛

Posted hulian425

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu-4810 Wall Painting 2013ACM/ICPC亚洲区南京站现场赛相关的知识,希望对你有一定的参考价值。

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4810

 

解题思路:

记录下每个数的各个位上1个数的和,根据题意,异或要产生数值,必须是取基数个1,通过组合数学的方法,比如要在6个1里面取三个1,则取得方法有C(6,3),那么如何可以快速取得C(6,3)呢?通过杨辉三角形打表即可

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;#define P 1000003
int n, c[1005][1005], sum[40], a, ans[1005], t;
// c[][]记录杨辉三角形
// sum[]记录每位上有多少个1;
// ans[]记录第k天有多少种方案
int main() {
// 杨辉三角形打表,记录C(m,n)
for (int i =0; i <= 1000; i++) { c[i][0] = 1; c[i][i] = 1; } for (int i =1; i <= 1000; i++) { for (int j = 1; j < i; j++) { c[i][j] = (c[i - 1][j] % P + c[i-1][j-1] %P) %P; } } while (~scanf("%d", &n)) { memset(sum, 0, sizeof(sum)); memset(ans, 0, sizeof(ans));
    // 将每位上有多少个1记录下来
for (int i= 0; i < n; i++) { int t; scanf("%d", &t); for (int j = 0; t;++j,t>>=1) { if (t%2) sum[j]++; //该位上有1; } } for (int k = 1; k <= n; k++) { for (int i = 0; i < 32; i++) { for (int j = 1; j <= sum[i] && j <= k; j += 2){ t = (long long )c[sum[i]][j]* c[n-sum[i]][k-j] %P*(1<<i)%P; ans[k] = (ans[k] + t) % P; } } } for (int k = 1; k <= n; k++) printf("%d%c", ans[k], k < n? : ); } }

以上是关于hdu-4810 Wall Painting 2013ACM/ICPC亚洲区南京站现场赛的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4810 Wall Painting (位操作-异或)

hdu-4810 Wall Painting 2013ACM/ICPC亚洲区南京站现场赛

XCPC真题:Bits Reverse | Empty Squares | Wall Painting

[Codefoeces398B]Painting The Wall(概率DP)

USACO20JAN Cave Painting 并查集

codeforces 19/11/06 div2C. Tile Painting