题目链接:

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一样。

 for(int i = ; i < m; i++)
{
for(int j = ; j < (<<m); j++)
{
if(j & (<<i))
sum[j] += sum[j ^ (<<i)];
}
}

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

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

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

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

 #include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + ;
typedef long long ll;
ll a[maxn], sum[maxn];
int main()
{
int T, n, x;
cin >> T;
while(T--)
{
scanf("%d", &n);
memset(a, , sizeof(a));
memset(sum, , sizeof(sum));
for(int i = ; i < n; i++)
{
scanf("%d", &a[i]);
sum[a[i]]++;
}
int m = ;
for(int i = ; i < m; i++)
{
for(int j = ; j < (<<m); j++)
{
if(j & (<<i))
sum[j] += sum[j ^ (<<i)];
}
}
ll ans = ;
for(int i = ; i < n; i++)
ans += sum[a[i]];
cout<<ans<<endl;
}
return ;
}

EOJ-3300 奇数统计(高维前缀和)的更多相关文章

  1. HDU.5765.Bonds(DP 高维前缀和)

    题目链接 \(Description\) 给定一张\(n\)个点\(m\)条边的无向图.定义割集\(E\)为去掉\(E\)后使得图不连通的边集.定义一个bond为一个极小割集(即bond中边的任意一个 ...

  2. 【洛谷5643】[PKUWC2018] 随机游走(Min-Max容斥+待定系数法+高维前缀和)

    点此看题面 大致题意: 从一个给定点出发,在一棵树上随机游走,对于相邻的每个点均有\(\frac 1{deg}\)的概率前往.多组询问,每次给出一个点集,求期望经过多少步能够访问过点集内所有点至少一次 ...

  3. BZOJ.5092.[Lydsy1711月赛]分割序列(高维前缀和)

    题目链接 \(Description\) \(Solution\) 首先处理\(a_i\)的前缀异或和\(s_i\).那么在对于序列\(a_1,...,a_n\),在\(i\)位置处分开的价值为:\( ...

  4. SPOJ.TLE - Time Limit Exceeded(DP 高维前缀和)

    题目链接 \(Description\) 给定长为\(n\)的数组\(c_i\)和\(m\),求长为\(n\)的序列\(a_i\)个数,满足:\(c_i\not\mid a_i,\quad a_i\& ...

  5. LOJ2542 PKUWC2018 随机游走 min-max容斥、树上高斯消元、高维前缀和、期望

    传送门 那么除了D1T3,PKUWC2018就更完了(斗地主这种全场0分的题怎么会做啊) 发现我们要求的是所有点中到达时间的最大值的期望,\(n\)又很小,考虑min-max容斥 那么我们要求从\(x ...

  6. Luogu3175 HAOI2015 按位或 min-max容斥、高维前缀和、期望

    传送门 套路题 看到\(n \leq 20\),又看到我们求的是最后出现的位置出现的时间的期望,也就是集合中最大值的期望,考虑min-max容斥. 由\(E(max(S)) = \sum\limits ...

  7. BZOJ5092:[Lydsy1711月赛]分割序列(贪心,高维前缀和)

    Description 对于一个长度为n的非负整数序列b_1,b_2,...,b_n,定义这个序列的能量为:f(b)=max{i=0,1,...,n}((b_1 xor b_2 xor...xor b ...

  8. HihoCoder - 1496:寻找最大值(高维前缀和||手动求子集)

    描述 给定N个数A1, A2, A3, ... AN,小Ho想从中找到两个数Ai和Aj(i ≠ j)使得乘积Ai × Aj × (Ai AND Aj)最大.其中AND是按位与操作. 小Ho当然知道怎么 ...

  9. BZOJ:5092 [Lydsy1711月赛]分割序列(贪心&高维前缀和)

    Description 对于一个长度为n的非负整数序列b_1,b_2,...,b_n,定义这个序列的能量为:f(b)=max{i=0,1,...,n}((b_1 xor b _2 xor...xor ...

随机推荐

  1. Struts2 入门介绍(一)

    一.什么是Struts2 1.Struts2是一个开发框架,应用于JavaEE三层架构中的web层. 2.Struts2框架是在Struts1和webwork基础上发展的一个全新的框架. 3.Stru ...

  2. C++的中英文字符串表示(string,wstring)

    在C++中字符串类的string的模板原型是basic_string template <class _Elem, class traits = char_traits<_Elem> ...

  3. python 包管理工具Pipenv

    Kenneth Reitz的最新工具Pipenv可以用于简化Python项目中依赖项的管理. 它汇集了Pip,Pipfile和Virtualenv的功能,是一个强大的命令行工具. 入门 首先使用pip ...

  4. Splunk数据处理

    0.提要 本篇主要从技术层面针对Splunk Enterprise中关于数据处理的概念.过程与部件进行了概要性总结. 1.数据管理基本概念 索引(index):Splunk用于存储事件的数据仓库: 索 ...

  5. 铵钮提交事件PostBack之后,一些动态加载的物件丢失

    今早起来,发现skype有网友留言,情况大约如下,不过Insus.NET还是先感谢网友的测试.http://www.cnblogs.com/insus/p/3193619.html  如果你有看此篇博 ...

  6. android 生成随机数

    /**  * 随机数.字母 工具类  * Created by admin on 2017/2/20.  */ public class RandomUntil {     /**      * 生成 ...

  7. springmvc + spring + ibatis + mysql

    1.spring mvc 官网下载:https://repo.spring.io/webapp/#/artifacts/browse/simple/General/libs-release-local ...

  8. tomcat启动编码等部署遇到问题

    版权声明:本文为博主原创文章,转载请注明文章链接.https://blog.csdn.net/xiaoanzi123/article/details/58254318 2017-02-27 21:01 ...

  9. TCP keepalive长连接心跳保活

    比如:客户端与服务端进行握手时,经常无法握手成功,收不到回复: 需要建立保活机制. 1. 服务端Linux服务器新增系统内核参数配置. 在/etc/sysctl.conf文件中再添加如: #允许的持续 ...

  10. JavaScript switch语句

    JavaScriptswitch语句 switch语句用于基于不同的条件来执行不同的动作. JavaScript switch 语句 使用switch语句可以进行多项选择. 语法: switch( 变 ...