题目大意:给你一个序列,你可以在序列中任选一个子序列,求子序列每一项的积是一个平方数的方案数。

1<=a[i]<=70

因为任何一个大于2的数都可以表示成几个质数的幂的乘积

所以我们预处理70以内的质数,把它作为二进制状压的状态,每个在序列中出现数Hash一下,组合数推一下

所以把奇次幂的状态表示为1,偶次幂的状态就是0,比如6就是11,42就是1011

而平方数的每个质因子的指数都是偶数,所以最终结果的状态就是0000000...

转移的过程,两个数的乘积,就是这两个数的质因子二进制的状态的合并,即异或(xor)运算

卡常很恶心,懒得进一步优化了

好吧据说可以推出结论,这个组合数加起来其实是2的幂次

 #include <cstdio>
#include <algorithm>
#include <cstring>
#define N 100100
#define M 75
#define mod 1000000007
#define C(m,n) (((fac[n]*inv[m])%mod*inv[n-m])%mod)
#define ll long long
using namespace std; int xx,n,now,lst;
int hx[M];
ll x,y,t;
ll inv[N],fac[N],f[][(<<)+];
int pr[]={,,,,,,,,,,,,,,,,,,};
int gc()
{
int rett=,fh=;char c=getchar();
while(c<''||c>'') {if(c=='-')fh=-; c=getchar();}
while(c>=''&&c<='') {rett=rett*+c-'';c=getchar();}
return rett*fh;
}
void exgcd(ll a,ll b)
{
if(b==) {x=,y=;}
else {exgcd(b,a%b);t=x;x=y;y=t-a/b*y;}
}
void get_inv()
{
inv[]=inv[]=,fac[]=fac[]=;
for(ll i=;i<=n;i++)
{
exgcd(i,mod);
fac[i]=(fac[i-]*i)%mod;
x=(x%mod+mod)%mod;
inv[i]=(inv[i-]*x)%mod;
}
} int main()
{
//freopen("aa.in","r",stdin);
scanf("%d",&n);
for(int i=;i<=n;i++) xx=gc(),hx[xx]++;
get_inv();
now=,lst=,f[][]=;
for(int i=;i<=;i++)
{
if(!hx[i]) continue;
int s=,x=i;
for(int j=;j<;j++)
{
while(x%pr[j]==)
{
s^=(<<j);
x/=pr[j];
}
}
for(int p=;p<(<<);p++)
{
if(!f[lst][p]) continue;
for(int j=;j<=hx[i];j++)
{
if(j&)
{
f[now][p^s]+=(f[lst][p]*C(j,hx[i]))%mod;
f[now][p^s]%=mod;
}else{
f[now][p]+=(f[lst][p]*C(j,hx[i]))%mod;
f[now][p]%=mod;
}
}
f[lst][p]=;
}
swap(now,lst);
}
printf("%I64d\n",f[lst][]-);
return ;
}

CF895C Square Subsets (组合数+状压DP+简单数论)的更多相关文章

  1. Codeforces 895C Square Subsets(状压DP 或 异或线性基)

    题目链接  Square Subsets 这是白书原题啊 先考虑状压DP的做法 $2$到$70$总共$19$个质数,所以考虑状态压缩. 因为数据范围是$70$,那么我们统计出$2$到$70$的每个数的 ...

  2. Codeforces 895C Square Subsets:状压dp【组合数结论】

    题目链接:http://codeforces.com/problemset/problem/895/C 题意: 给你n个数a[i].(n <= 10^5, 1 <= a[i] <= ...

  3. 2019.02.09 bzoj2560: 串珠子(状压dp+简单容斥)

    传送门 题意简述:nnn个点的带边权无向图,定义一个图的权值是所有边的积,问所有nnn个点都连通的子图的权值之和. 思路: fif_ifi​表示保证集合iii中所有点都连通其余点随意的方案数. gig ...

  4. Codeforces 895C - Square Subsets 状压DP

    题意: 给了n个数,要求有几个子集使子集中元素的和为一个数的平方. 题解: 因为每个数都可以分解为质数的乘积,所有的数都小于70,所以在小于70的数中一共只有19个质数.可以使用状压DP,每一位上0表 ...

  5. 简单状压dp的思考 - 最大独立集问题和最大团问题 - 贰

    接着上文 题目链接:最大独立集问题 上次说到,一种用状压DP解决任意无向图最大团问题(MCP)的方程是: 注:此处popcountmax代表按照二进制位下1的个数作为关键字比较,即选择二进制位下1的个 ...

  6. 简单状压dp的思考 - 最大独立集问题和最大团问题 - 壹

    本文参考:CPH ,USACO Guide (大佬请越过,这是初学笔记,不要吐槽内容) 前置知识:位运算基础,动态规划基础 介绍 状态是元素的子集的动态规划算法,可以用位运算来高效的优化. 那么第一道 ...

  7. POJ 3254 简单状压DP

    没什么可说的,入门级状压DP.直接撸掉 #include <iostream> #include <cstring> #include <cstdlib> #inc ...

  8. poj2411 Mondriaan's Dream[简单状压dp]

    $11*11$格子板上铺$1*2$地砖方案.以前做过?权当复习算了,毕竟以前学都是浅尝辄止的..常规题,注意两个条件:上一行铺竖着的则这一行同一位一定要铺上竖的,这一行单独铺横的要求枚举集合中出现连续 ...

  9. HDU 4917 Permutation(拓扑排序 + 状压DP + 组合数)

    题目链接 Permutation 题目大意:给出n,和m个关系,每个关系为ai必须排在bi的前面,求符合要求的n的全排列的个数. 数据规模为n <= 40,m <= 20. 直接状压DP空 ...

随机推荐

  1. Codeforces 787B Not Afraid( 水 )

    链接:传送门 题意:判断 m 组数,如果某一组中出现负数就判断这一组中是否存在与之相反的数,如果每一组中都满足要求则输出 "NO" 反之输出 "YES" 思路: ...

  2. linux 遇到(vsftpd)—500 OOPS:chroot

    今天在用vsftpd 时出现一个问题: 500 OOPS:chroot 解决办法: 1.关闭SELINUX [root@localhost ~]#vi /etc/sysconfig/selinux # ...

  3. vue 2.0 购物车小球抛物线

    备注:此项目模仿 饿了吗.我用的是最新的Vue, 视频上的一些写法已经被废弃了. 布局代码 <div class="ball-container"> <trans ...

  4. Django入门--创建项目及应用

    Django是用于后台处理的web应用框架.用户通过浏览器输入网址,向http服务器发起访问网页的请求,http服务器(Apache/Nginx)接收到用户请求后,把请求发送给web应用框架进行处理, ...

  5. 《你又怎么了我错了行了吧》【Alpha】Scrum meeting 2

    第二天 日期:2019/6/15 前言: 第2次会议在9C-405召开 进行第一天工作的检查,开始第二天工作的安排和学习 1.1 今日完成任务情况以及明天任务安排 姓名 当前阶段任务 下一阶段任务 刘 ...

  6. 参数化取值策略Sequential

    1.Sequential+Each iteration(顺序方式+每次迭代更新取值),设置Run—Logic中action循环迭代11次,并运行以上脚本,结果如下:     2.Sequential+ ...

  7. 基于【SpringBoot】的微服务【Jenkins】自动化部署

    最近,也是抽空整理了一些在工作中积累的经验,通过博客记录下来分享给大家,希望能对大家有所帮助: 一.关于自动化部署 关于自动化部署的优点,我就不在这里赘述了:只要想想手工打包.上传.部署.重启的种种, ...

  8. win7下virtualbox遇到的问题

    问题1:无法创建unbuntu 64bit 虚拟机           安装完virtualbox后,新建虚拟机.类型选择为Linux时,版本下拉选项只有ubuntu 32bit,无ubuntu 64 ...

  9. 【Python】python网络协议

    套接字是常见的低级别的网络通讯协议,在此基础上,还有很多其他的网络通讯协议.用于实现client-server的网络互联,以下对这些协议做一个简单的介绍. 1.文件传输 FTP:文件传输协议.能够上传 ...

  10. 疯狂Java学习笔记(72)-----------大话程序猿面试

    大话程序猿面试 10个我最喜欢问程序猿的面试问题 程序猿面试不全然指南 10个经典的C语言面试基础算法及代码 程序猿的10大成功面试技巧 程序猿选择公司的8个标准 编程开发 8个值得关注的PHP安全函 ...