CF895C Square Subsets (组合数+状压DP+简单数论)
题目大意:给你一个序列,你可以在序列中任选一个子序列,求子序列每一项的积是一个平方数的方案数。
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+简单数论)的更多相关文章
- Codeforces 895C Square Subsets(状压DP 或 异或线性基)
题目链接 Square Subsets 这是白书原题啊 先考虑状压DP的做法 $2$到$70$总共$19$个质数,所以考虑状态压缩. 因为数据范围是$70$,那么我们统计出$2$到$70$的每个数的 ...
- Codeforces 895C Square Subsets:状压dp【组合数结论】
题目链接:http://codeforces.com/problemset/problem/895/C 题意: 给你n个数a[i].(n <= 10^5, 1 <= a[i] <= ...
- 2019.02.09 bzoj2560: 串珠子(状压dp+简单容斥)
传送门 题意简述:nnn个点的带边权无向图,定义一个图的权值是所有边的积,问所有nnn个点都连通的子图的权值之和. 思路: fif_ifi表示保证集合iii中所有点都连通其余点随意的方案数. gig ...
- Codeforces 895C - Square Subsets 状压DP
题意: 给了n个数,要求有几个子集使子集中元素的和为一个数的平方. 题解: 因为每个数都可以分解为质数的乘积,所有的数都小于70,所以在小于70的数中一共只有19个质数.可以使用状压DP,每一位上0表 ...
- 简单状压dp的思考 - 最大独立集问题和最大团问题 - 贰
接着上文 题目链接:最大独立集问题 上次说到,一种用状压DP解决任意无向图最大团问题(MCP)的方程是: 注:此处popcountmax代表按照二进制位下1的个数作为关键字比较,即选择二进制位下1的个 ...
- 简单状压dp的思考 - 最大独立集问题和最大团问题 - 壹
本文参考:CPH ,USACO Guide (大佬请越过,这是初学笔记,不要吐槽内容) 前置知识:位运算基础,动态规划基础 介绍 状态是元素的子集的动态规划算法,可以用位运算来高效的优化. 那么第一道 ...
- POJ 3254 简单状压DP
没什么可说的,入门级状压DP.直接撸掉 #include <iostream> #include <cstring> #include <cstdlib> #inc ...
- poj2411 Mondriaan's Dream[简单状压dp]
$11*11$格子板上铺$1*2$地砖方案.以前做过?权当复习算了,毕竟以前学都是浅尝辄止的..常规题,注意两个条件:上一行铺竖着的则这一行同一位一定要铺上竖的,这一行单独铺横的要求枚举集合中出现连续 ...
- HDU 4917 Permutation(拓扑排序 + 状压DP + 组合数)
题目链接 Permutation 题目大意:给出n,和m个关系,每个关系为ai必须排在bi的前面,求符合要求的n的全排列的个数. 数据规模为n <= 40,m <= 20. 直接状压DP空 ...
随机推荐
- 面试准备专题——SOA架构
- STM32 ADC多通道转换DMA模式与非DMA模式两种方法(HAL库)
一.非DMA模式(转) 说明:这个是自己刚做的时候百度出来的,不是我自己做出来的,因为感觉有用就保存下来做学习用,原文链接:https://blog.csdn.net/qq_24815615/arti ...
- Ubuntu 15.10配置OpenCV
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50635705 1 安装前准备 安装以下 ...
- 命令模式之2 Invoker Vs. Client
当程序中直接编写下达命令的语句如new Cmd1().execute()时.一般会将调用者与客户类合二为一. 在GUI程序中.下达命令的语句通常包括在底层框架中.或者说底层框架包括了调用者.这时程序猿 ...
- reactjs simple text editor
import React, { Component } from 'react' import PubSub from 'pubsub' import GlobalVars from 'globalV ...
- tapestry3创建自己定义组件
两种方法创建自己定义标签: 一.通过AbstractComponent父类渲染,此种方法直接在java类中编写页面脚本.然后输出. 1.编写java类com/ailk/ech/ecop/view/te ...
- linux中设置TAB键的宽度
对于编程的人员来说,常常须要排版代码,这时候就须要TAB键,但TAB键的宽度太大,非常有可能代码太长,延伸到下一行,这个时候你就须要设置TAB键的宽度了. linux下设置TAB键的宽度,做法例如以下 ...
- 淘宝数据库OceanBase SQL编译器部分 源代码阅读--生成逻辑计划
淘宝数据库OceanBase SQL编译器部分 源代码阅读--生成逻辑计划 SQL编译解析三部曲分为:构建语法树.生成逻辑计划.指定物理运行计划. 第一步骤,在我的上一篇博客淘宝数据库OceanBas ...
- QFileSystemModel只显示名称,不显示size,type,modified
Qt 提供的 QFileSystemModel可以提供文件目录树预览功能,但是预览的都自带了Name,size,type, modified等信息.我现在只想显示name这一列,不想显示size,ty ...
- Qt 图像处理之 灰度变换
对图像的亮度.对照度进行变换是非经常常使用的一种图像处理操作,可是Qt 本身却没有提供对应的功能代码.因此我写了个简单的类来实现这些操作.我把这个类称为 BrightnessMapper. 代码例如以 ...