zoukankan      html  css  js  c++  java
  • HDU-4810 Wall Paiting 位运算 , 组合

    HDU-4810 Wall Paiting

    题意

    给定(n) 个数,分别输出(i) 个答案,每个答案表示从(n) 个数中选择(C_n^i) 组数,计算这组数的异或和,再将这(C_n^i) 组数的和相加。

    分析

    由于是异或,各位之间不相互影响,我们考虑每个数每一位对答案的贡献,考虑二进制的第(i) 位,如果第(i) 位对答案有贡献,也就是(1) ,那么这一位一定是由奇数个1异或得到,所以我们其实只要统计第(i) 位为(1) 的个数,对这个排列组合即可。注意还要乘上(2^i)

    代码

    ll C[1005][1005];
    int num[35];
    void get_C()
    {
        C[0][0] = 1;
        for (int i = 1; i <= 1003; i++)
        {
            C[i][0] = 1;
            for (int j = 1; j <= i; j++)
                C[i][j] = C[i - 1][j] + C[i - 1][j - 1], C[i][j] %= MOD;
        }
    }
    
    int main() {
        int n;
        get_C();
        while (~scanf("%d", &n)) {
            memset(num, 0, sizeof num);
            for (int i = 0; i < n; i++) {
                ll x = readint();
                for (int j = 32; j >= 0; j--)
                    if ((1ll << j) & x) num[j]++;
            }
            for (int i = 1; i <= n; i++) {
                ll sum = 0;
                for (int j = 32; j >= 0; j--) {
                    ll res = 0;
                    for (int k = 1; k <= i; k += 2) {
                        res += C[num[j]][k] * C[n - num[j]][i - k] % MOD;
                        res %= MOD;
                    }
                    sum = (ksm(2, (ll)j, MOD) * res % MOD + sum) % MOD;
                }
                Put(sum);
                putchar(i == n ? '
    ' : ' ');
            }
        }
    }
    
  • 相关阅读:
    第十四周学习进度总结
    第十三周学习进度总结
    第十二周学习进度总结
    第十一周学习进度总结
    第十周学习进度总结
    第九周学习进度总结
    第八周学习进度总结
    day16-机器学习十讲第一讲
    day15-验证码识别
    day14-卷积网络识别手写数字
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13562222.html
Copyright © 2011-2022 走看看