Codeforces 895C Square Subsets:状压dp【组合数结论】
题目链接:http://codeforces.com/problemset/problem/895/C
题意:
给你n个数a[i]。(n <= 10^5, 1 <= a[i] <= 70)
问你有多少非空子集s,使得 ∏(s[i])为完全平方数。
题解:
由于a[i] <= 70,而70以内的质数只有19个,显然可以状压。
由于一个数是完全平方数的条件是:它的每种质因子的指数为偶数
所以先处理出对于每个a[i],它的所有质因子指数的奇偶性f[i]。
对于f[i]的每一位,0表示它的质因子prime[i]的指数为偶,1代表为奇数。
另外由于n比较大,所以dp中状态不能是“当前考虑到a[i]”,而应该是“当前考虑到数字i”。
所以之前要统计一下为数字i的a[j]的个数cnt[i]。(x <= 70)
然后开始状压。
表示状态:
dp[i][state]表示当前考虑到数字i,子集和的质因子指数的奇偶性为state,此时的子集方案数
找出答案:
由于1到70的所有数都会考虑一遍,且最终的子集和的质因子的指数都应该为偶数
另外由于要求是非空子集,最终答案要-1
所以ans = dp[71][0] - 1
如何转移:
对于数字i来说,如果cnt[i] == 0,则直接将所有dp[i][state]复制到dp[i+1][state]即可。
否则分两种情况:数字i选偶数个 or 奇数个。选偶数个i不会影响子集和质因子指数的奇偶性,而奇数个会影响。
(1)偶数个:dp[i+1][state] += dp[i][state] * C(n,m),其中m = 0,2,4,6,8...
(2)奇数个:dp[i+1][state^f[i]] += dp[i][state] * C(n,m),其中m = 1,3,5,7,9...
有一个结论:∑ C(n,{0,2,4,6,8...}) = ∑ C(n,{1,3,5,7,9...}) = 2^(n-1)
之前预处理所有p[i] = 2^i % MOD即可。
边界条件:
dp[1][0] = 1
others = 0
AC Code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 100005
#define MAX_A 75
#define MAX_S 550000
#define MOD 1000000007 using namespace std; const int prime[]={,,,,,,,,,,,,,,,,,,}; int n;
int p[MAX_N];
int f[MAX_A];
int cnt[MAX_A];
int dp[MAX_A][MAX_S]; void read()
{
cin>>n;
memset(cnt,,sizeof(cnt));
int a;
for(int i=;i<=n;i++)
{
cin>>a;
cnt[a]++;
}
} void cal_f()
{
memset(f,,sizeof(f));
for(int i=;i<=;i++)
{
int t=i;
for(int j=;j<;j++)
{
while(t%prime[j]==)
{
f[i]^=(<<j);
t/=prime[j];
}
}
}
} void cal_p()
{
p[]=;
for(int i=;i<MAX_N;i++) p[i]=(p[i-]<<)%MOD;
} void cal_dp()
{
memset(dp,,sizeof(dp));
dp[][]=;
for(int i=;i<=;i++)
{
if(!cnt[i])
{
for(int state=;state<(<<);state++)
{
dp[i+][state]=dp[i][state];
}
}
else
{
for(int state=;state<(<<);state++)
{
if(dp[i][state])
{
dp[i+][state]=(dp[i+][state]+(long long)dp[i][state]*p[cnt[i]-])%MOD;
dp[i+][state^f[i]]=(dp[i+][state^f[i]]+(long long)dp[i][state]*p[cnt[i]-])%MOD;
}
}
}
}
} void work()
{
cal_f();
cal_p();
cal_dp();
cout<<dp[][]-<<endl;
} int main()
{
read();
work();
}
Codeforces 895C Square Subsets:状压dp【组合数结论】的更多相关文章
- Codeforces 895C - Square Subsets 状压DP
题意: 给了n个数,要求有几个子集使子集中元素的和为一个数的平方. 题解: 因为每个数都可以分解为质数的乘积,所有的数都小于70,所以在小于70的数中一共只有19个质数.可以使用状压DP,每一位上0表 ...
- Codeforces 895C Square Subsets(状压DP 或 异或线性基)
题目链接 Square Subsets 这是白书原题啊 先考虑状压DP的做法 $2$到$70$总共$19$个质数,所以考虑状态压缩. 因为数据范围是$70$,那么我们统计出$2$到$70$的每个数的 ...
- Codeforces 895C - Square Subsets
895C - Square Subsets 思路:状压dp. 每个数最大到70,1到70有19个质数,给这19个质数标号,与状态中的每一位对应. 状压:一个数含有这个质因子奇数个,那么他状态的这一位是 ...
- codeforces Diagrams & Tableaux1 (状压DP)
http://codeforces.com/gym/100405 D题 题在pdf里 codeforces.com/gym/100405/attachments/download/2331/20132 ...
- Codeforces 917C - Pollywog(状压 dp+矩阵优化)
UPD 2021.4.9:修了个 typo,为啥写题解老出现 typo 啊( Codeforces 题目传送门 & 洛谷题目传送门 这是一道 *2900 的 D1C,不过还是被我想出来了 u1 ...
- Codeforces 79D - Password(状压 dp+差分转化)
Codeforces 题目传送门 & 洛谷题目传送门 一个远古场的 *2800,在现在看来大概 *2600 左右罢( 不过我写这篇题解的原因大概是因为这题教会了我一个套路罢( 首先注意到每次翻 ...
- Codeforces 544E Remembering Strings 状压dp
题目链接 题意: 给定n个长度均为m的字符串 以下n行给出字符串 以下n*m的矩阵表示把相应的字母改动成其它字母的花费. 问: 对于一个字符串,若它是easy to remembering 当 它存在 ...
- codeforces 21D. Traveling Graph 状压dp
题目链接 题目大意: 给一个无向图, n个点m条边, 每条边有权值, 问你从1出发, 每条边至少走一次, 最终回到点1. 所走的距离最短是多少. 如果这个图是一个欧拉回路, 即所有点的度数为偶数. 那 ...
- CodeForces 327E Axis Walking(状压DP+卡常技巧)
Iahub wants to meet his girlfriend Iahubina. They both live in Ox axis (the horizontal axis). Iahub ...
- Codeforces ----- Kefa and Dishes [状压dp]
题目传送门:580D 题目大意:给你n道菜以及每道菜一个权值,k个条件,即第y道菜在第x道后马上吃有z的附加值,求从中取m道菜的最大权值 看到这道题,我们会想到去枚举,但是很显然这是会超时的,再一看数 ...
随机推荐
- iOS反射:把对象直接转化成NSDictionary
在IOS的网络编程中,通常我们需要将一些实体数据保存到NSDictionary,在获得NSDictionary后即可直接使用iOS 5后的NSJSONSerialization类型的dataWithJ ...
- 阿里云 如何减少备份使用量? mysql数据库的完整备份、差异备份、增量备份
RDS for MySQL备份.SQL审计容量相关问题_MYSQL使用_技术运维问题_云数据库 RDS 版-阿里云 https://help.aliyun.com/knowledge_detail/4 ...
- 任务04——对四则运算小程序的进一步改进,并学习 Git 中 Branch 的用法
https://github.com/jinxiaohang/Operation/tree/test01 对于任务2的代码进行优化修改感觉很麻烦,所以直接选择重写代码完成任务四, 任务四很早就发布了, ...
- python面试题(七)
1 什么是局域网.广域网.城域网? ①局域网LAN(Local Area Network):一般指覆盖范围在10公里以内,一座楼房或一个单位内部的网络.由于传输距离直接影响传输速度,因此,局域网内的通 ...
- java基础—Hashtable,HashMap,TreeMap的差别
Hashtable : 此类实现一个哈希表,该哈希表将键映射到对应的值.不论什么非null 对象都能够作键值,是线程不同步的 HashMap : 基于哈希表的Map接口的实现.此实现提供全部可选的映 ...
- Linux中进程在前后台的切换
把进程放入后台执行 tar -zcf etc.tar.gz /etc &把进程放入后台暂停 在命令执行的过程中,按下ctrl+z 查看后台的命令 jobs[root@localhost tem ...
- Oracle学习笔记—数据库,实例,表空间,用户、表之间的关系
之前一直使用的关系型数据库是Mysql,而新公司使用Oracle,所以最近从网上搜集了一些资料,整理到这里,如果有不对的地方,欢迎大家讨论. 基本概念: 数据库:Oracle 数据库是数据的物理存储. ...
- zabbix-2.4.8-1添加nginx状态监控
前期准备:nginx在编译是必须要加如下参数: 并且要在nginx的配置文件中添加如下配置: server { listen *: default_server; server_name localh ...
- 我的npm笔记
本文记录一些npm的使用技巧,主要包括自己常用的命令,做个备忘. NPM 是什么? NPM是NodeJS的包管理工具,现在已经进一步发展,致力于为很多其他平台提供包管理工具,其核心思想就是让包的安装更 ...
- Python学习进程(7)字符串
本节介绍字符串的创建与操作方法. (1)创建字符串: 创建字符串既可以用单引号也可以用双引号: root@SJM:/home/sunjimeng/桌面# cat text.py ...