• EOJ-3300 奇数统计(高维前缀和)


    题目链接:

    https://acm.ecnu.edu.cn/problem/3300/

    题目大意:

    给n个数,求在n个数中选两个数(可重复),使得这两个数的组合数是奇数,求总共有多少种取法。

    解题思路:

    组合数Cnm奇偶性判断:

    n & m == m 成立则组合数为奇数

    一开始没什么的思路,直接暴力超时,后来看到Lucas定理,发现上面那个式子的本质就是从这里推导出来的。

    Lucas定理:

    组合数判断奇数的话就是转化成上述定理中p = 2

    是否为1,利用Lucas定理,先把化为二进制,这样它们都是01序列了。我们又知道

         。这样中为0的地方对应的中的位置只有一种可能,那就是0

    这样n&m = m的本质就是二进制中n对应的0得地方,m也对应为0。

    然而,就是这个本质,就可以解这道题目

    有位大佬一句话点醒了我,n&m = m说明m是n的子集。

    对的,用二进制表示子集的时候,就是这样,m是n的子集,等价于n为0的位置m一定为0,n为1

    的位置,m可以为1,可以为0。

    然后对于每个n,求出它的子集的数目即可。

    对于求子集,大佬教的方法是高维前缀和,代码很简单,就三行,和状态压缩DP一样。

    1 for(int i = 0; i < m; i++)
    2 {
    3     for(int j = 0; j < (1<<m); j++)
    4     {
    5         if(j & (1<<i))
    6               sum[j] += sum[j ^ (1<<i)];
    7     }
    8 }   

    举个例子,sum[0101] = sum[0101] + sum[0100] + sum[0001] + sum[0000]

    sum[i]就表示i二进制的所有子集的权值之和

    对于组合数n & m == m  m是n的子集,

    先统计每个数出现的次数,然后对于每个数,统计它的子集的个数即可,最后答案相加。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 1e6 + 10;
     4 typedef long long ll;
     5 ll a[maxn], sum[maxn];
     6 int main()
     7 {
     8     int T, n, x;
     9     cin >> T;
    10     while(T--)
    11     {
    12         scanf("%d", &n);
    13         memset(a, 0, sizeof(a));
    14         memset(sum, 0, sizeof(sum));
    15         for(int i = 0; i < n; i++)
    16         {
    17             scanf("%d", &a[i]);
    18             sum[a[i]]++;
    19         }
    20         int m = 17;
    21         for(int i = 0; i < m; i++)
    22         {
    23             for(int j = 0; j < (1<<m); j++)
    24             {
    25                 if(j & (1<<i))
    26                     sum[j] += sum[j ^ (1<<i)];
    27             }
    28         }
    29         ll ans = 0;
    30         for(int i = 0; i < n; i++)
    31             ans += sum[a[i]];
    32         cout<<ans<<endl;
    33     }
    34     return 0;
    35 }
  • 相关阅读:
    Excel Sheet Column Number
    HappyNum
    isIsomorphic
    Contains DuplicateII
    iis7 设置http 自动跳转到https
    php 安装redis
    java 打包 war包
    NPOI 操作excel之 将图片插入到指定位置;
    nopi 简洁笔记
    vs11 微软下载地址
  • 原文地址:https://www.cnblogs.com/fzl194/p/9045315.html
Copyright © 2020-2023  润新知