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道菜的最大权值 看到这道题,我们会想到去枚举,但是很显然这是会超时的,再一看数 ...
随机推荐
- E QUERY [main] SyntaxError: identifier starts immediately after numeric literal mongodb mapReduce 异常分析 集合命名规范
异常信息 repl_test:PRIMARY> db.0917order_totals_b.find()2018-09-28T15:13:03.992+0800 E QUERY [main] S ...
- C# 调用ArcGIS server admin api
一.AGS server admin api 介绍 1.1什么是admin api AGS Server Admin api 官方的称呼是 AGS Server administrator api, ...
- Java源码之Object
本文出自:http://blog.csdn.net/dt235201314/article/details/78318399 一丶概述 JAVA中所有的类都继承自Object类,就从Object作为源 ...
- 整理前端css/js/jq常见问题及解决方法(1)
1. 兼容ie8圆角的解决方法:下载ie-css3.htc文件在css中加入behavior:url(ie-css3.htc);z-index:3; position:relative 即可 2. 去 ...
- Python3.6全栈开发实例[003]
3.检查传入列表的长度,如果大于2,将列表的前两项内容返回给调用者. li = [11,22,33,44,55,66,77,88,99,000,111,222] def func3(lst): if ...
- Python3.6全栈开发实例[021]
21.给出一个纯数字列表. 请对列表进行排序(升级题). 思路: (1)完成a和b的数据交换. 例如, a = 10, b = 24 交换之后, a = 24, b = 10(2)循环列表. 判断a[ ...
- 【WEB HTTP】缓存
1. HTTP并不支持兄弟缓存,所以人们通过一些协议对HTTP进行了扩展,比如因特网缓存协议(Internet Cache Protocol, ICP)和超文本缓存协议(HyperText Cachi ...
- Python之匿名函数(Day18)
匿名函数 为了解决那些功能很简单的的需求而设计的一句话函数 #这段代码 def calc(n): return n**n print(calc(10)) #换成匿名函数 calc = lambda n ...
- JavaScript:学习笔记(6)——New运算符
JavaScript:学习笔记(6)——New运算符 new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例. 快速开始 当你使用new关键字的时候,会 创建一个新的对象 将th ...
- $Java HttpClient库的使用
(一)简介 HttpClient是Apache的一个开源库,相比于JDK自带的URLConnection等,使用起来更灵活方便. 使用方法可以大致分为如下八步曲: 1.创建一个HttpClient对象 ...