[SDOI2015]序列统计(多项式快速幂)
题目描述
小C有一个集合S,里面的元素都是小于M的非负整数。他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S。小C用这个生成器生成了许多这样的数列。但是小C有一个问题需要你的帮助:给定整数x,求所有可以生成出的,且满足数列中所有数的乘积mod M的值等于x的不同的数列的有多少个。小C认为,两个数列{Ai}和{Bi}不同,当且仅当至少存在一个整数i,满足Ai≠Bi。另外,小C认为这个问题的答案可能很大,因此他只需要你帮助他求出答案mod 1004535809的值就可以了。
题解
先考虑一个dp,就是设dp[i][j]表示已经构造好了前i个元素,它们的乘积为j的方案数。
转移:dp[i][j]=dp[i-1][k]*f[j/k]
看起来很像是卷积然鹅不是,他们中间是乘法关系而不是加法。
这时我们考虑一个限制,就是m是一个质数。
它有什么好处,就是当x,y互质时,那么x1x2....xy-1会遍历0-y-1的所有数。、
这样我们可以把1-m-1代换一下。
dp[i][j]=dp[i-1][k]*f[l] (gkgl=gj)
因为存在一一对应的关系,所以我们就可以代换了。
然后就变成了卷积的形式,多项式快速幂解决,因为每层的转移都是一样的。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 32002
using namespace std;
typedef long long ll;
const int mod=;
const int G=;
const int Gi=;
ll l,ny2,x,rev[N],L,n,m,a[N],b[N],s,g,c[N],tran[N],f[N];
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
inline ll power(ll x,ll y){
ll ans=;
while(y){if(y&)ans=ans*x%mod;x=x*x%mod;y>>=;}
return ans;
}
inline void NTT(ll *a,int tag){
for(int i=;i<l;++i)if(i>rev[i])swap(a[i],a[rev[i]]);
for(int i=;i<l;i<<=){
ll wn=power(tag==?G:Gi,(mod-)/(i<<));
for(int j=;j<l;j+=(i<<)){
ll w=;
for(int k=;k<i;++k,w=w*wn%mod){
int x=a[j+k],y=a[i+j+k]*w%mod;
a[j+k]=(x+y)%mod;a[i+j+k]=(x-y+mod)%mod;
}
}
}
}
inline void ch(ll a[],ll *b){
memcpy(c,a,sizeof(c));
NTT(c,);NTT(b,);
for(int i=;i<l;++i)b[i]=b[i]*c[i]%mod;
NTT(b,-);
for(int i=;i<l;++i)b[i]=b[i]*ny2%mod;
for(int i=m;i<(m<<);++i)(b[i-m]+=b[i])%=mod,b[i]=;
}
inline ll ksm(ll x,ll y,ll m){
ll ans=;
while(y){if(y&)ans=ans*x%m;x=x*x%m;y>>=;}
return ans;
}
inline int get_g(int m){
for(int i=;i<=m-;++i)if((m-)%i==)f[++f[]]=i;
for(int i=;;++i){
bool x=;
for(int j=;j<=f[]&&x;++j)if(ksm(i,f[j],m)==)x=;
if(x)return i;
}
}
int main(){
n=rd();m=rd();x=rd();s=rd();
g=get_g(m);
for(ll i=,k=;i<m-;++i,k=k*g%m)tran[k]=i;
m--;
l=;L=;
while(l<(m<<))l<<=,L++;int y;
ny2=power(l,mod-);
for(int i=;i<l;++i)rev[i]=(rev[i>>]>>)|((i&)<<(L-));
for(int i=;i<=s;++i){
y=rd();
if(y)a[tran[y]]=;
}
b[tran[]]=;
while(n){
if(n&)ch(a,b);
ch(a,a);n>>=;
}
cout<<b[tran[x]];
return ;
}
原根的求法:
暴力枚举,然后枚举m-1的所有质因子,若i^p==1则不是原根。
inline int get_g(int m){
for(int i=;i<=m-;++i)if((m-)%i==)f[++f[]]=i;
for(int i=;;++i){
bool x=;
for(int j=;j<=f[]&&x;++j)if(ksm(i,f[j],m)==)x=;
if(x)return i;
}
}
[SDOI2015]序列统计(多项式快速幂)的更多相关文章
- BZOJ 3992: [SDOI2015]序列统计 NTT+快速幂
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1155 Solved: 532[Submit][Statu ...
- P3321 [SDOI2015]序列统计 FFT+快速幂+原根
\(\color{#0066ff}{ 题目描述 }\) 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S.小C用这 ...
- 【BZOJ3992】[SDOI2015]序列统计 NTT+多项式快速幂
[BZOJ3992][SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属 ...
- BZOJ 3992: [SDOI2015]序列统计 快速幂+NTT(离散对数下)
3992: [SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S ...
- BZOJ 3992: [SDOI2015]序列统计 [快速数论变换 生成函数 离散对数]
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1017 Solved: 466[Submit][Statu ...
- 【洛谷3321_BZOJ3992】[SDOI2015]序列统计(原根_多项式)
题目: 洛谷3321 分析: 一个转化思路比较神(典型?)的题-- 一个比较显然的\(O(n^3)\)暴力是用\(f[i][j]\)表示选了\(i\)个数,当前积在模\(m\)意义下为\(j\)的方案 ...
- 3992: [SDOI2015]序列统计
3992: [SDOI2015]序列统计 链接 分析: 给定一个集和s,求多少个长度为n的序列,满足序列中每个数都属于s,并且所有数的乘积模m等于x. 设$f=\sum\limits_{i=0}^{n ...
- 【题解】SDOI2015序列统计
[题解]SDOI2015序列统计 来自永不AFO的YYB的推荐 这里是乘积,比较麻烦,不过由于给定的序列膜数是个小质数,所以可以\(O(m^2\log m)\)找原跟(实际上不需要这么多). 乘积有点 ...
- [SDOI2015]序列统计
[SDOI2015]序列统计 标签: NTT 快速幂 Description 给你一个模m意义下的数集,需要用这个数集生成一个数列,使得这个数列在的乘积为x. 问方案数模\(1004535809\). ...
随机推荐
- Hibernate two table same id
Hibernate更新数据(不用update也可以) - 森林木马 - 博客园 https://www.cnblogs.com/owenma/p/3481497.html hibernate级联更新会 ...
- Git之项目使用
现在最为盛行的版本控制器,非git莫属了, 那就看看在项目中我们是如何使用它的吧 一. 在已经存在秘钥对的情况下,我们需要在本地进行相关配置 git config --global user.name ...
- 优化MySQL性能的几种方法-总结
原文:http://bbs.landingbj.com/t-0-245601-1.html 1.要选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越 小,在它上 ...
- 学习笔记:filter_var()函数
PHP 过滤器用于对来自非安全来源的数据(比如用户输入)进行验证和过滤 filter_var() 函数通过指定的过滤器过滤变量. 如果成功,则返回已过滤的数据,如果失败,则返回 false. 语法 f ...
- Python基础知识1-基础语法
pyenv--版本管理工具(后续再补)可参见https://www.jianshu.com/p/8aaf2525fa80 冯诺依曼体系架构 编程基础 语言分类 低级语言到高级语言 高级语言 程序Pr ...
- PLA-1
PLA(Principal Component Analysis)主成分分析: 思路1:坐标旋转 1.数据分布以及投影: 2.特征值以及特征向量 思路2: 未完待续...
- 数据库语法group by
因为在做pgsql和mysql数据库时group by 有报错,但是在以前做mysql5.6的时候没有问题,虽然知道时违反了sql的语法问题,但是没有搞清楚什么原因,也找了不少资料,查找原因,在盆友的 ...
- environment variable
%ALLUSERSPROFILE% C:\ProgramData %APPDATA% C:\Users\cuthead\AppData\Roaming %COMMONPROGRAMFILES% C:\ ...
- Java精品文章收藏
1.JAVA进阶----ThreadPoolExecutor机制 待实践测试
- maven + bat 实现快速编译打包模块代码
pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...