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道菜的最大权值 看到这道题,我们会想到去枚举,但是很显然这是会超时的,再一看数 ...
随机推荐
- C#快速整理代码格式
删除最后一个大括号,再添加.vs自动整理代码结构.
- python系列三:python3运算符
'''python 没有自增运算符python 中,变量是以内容为基准而不是像 c 中以变量名为基准,所以只要你的数字内容是5,不管你起什么名字,这个变量的 ID 是相同的,同时也就说明了 pytho ...
- jQuery-PHP跨域请求数据
jQuery: //获取域名 function getDomain(url){ var a = document.createElement('a'); a.href = url; url=a.hos ...
- 接口测试工具 — jmeter(基本使用)
1.打开jemeter(bin目录下jemter.bat) 2.基本操作
- unity 人物描边锯齿
项目原来实现描边用了2个pass,一个pass cull back 渲染政策,一个cull front 渲染轮廓,但问题是锯齿特别明显 尝试了下边缘光实现描边,效果更不行,边线是断的
- Python— 匿名函数
匿名函数 匿名函数:为了解决那些功能很简单的需求而设计的 “一句话函数” #初始代码 def calc(n): return n**n print(calc(10)) #换成匿名函数 calc = ...
- ASP.NET MVC string赋值Html格式在显示View问题总结
ViewBag.Content = "<p>你好</p>"; string 类型的赋值一个 "<h1>你好</h1>&qu ...
- Python基础-set集合
1.集合的创建 s = set('fansik and fanjinbao') print(s) 打印结果(去掉了重复的字符):{'k', 'd', 'f', 'n', ' ', 'j', 'i', ...
- CoreThink主题开发(九)使用H-ui开发博客主题之用户个人主页
感谢H-ui.感谢CoreThink! 效果图: 这里使用table布局 /Theme/Blog/User/Index/home.html <extend name="$_home_ ...
- python基础28 -----python中sockserver模块
一.Python中的sockserver模块 1.该模块与sock模块不同之处是该模块自动帮我们分装好了一些功能,让我们在编程的时候直接调用这些功能就可以了,节省了编程步骤. 2.如图所示 注释:上图 ...