[SDOI2015]序列统计(NTT+求原根)
题目
挺好的题!!!
做法
\(f[i][j]\)为第\(i\)个数前缀积在模\(M\)意义下为\(j\)
显然是可以快速幂的:$$f[2*i][j]=\sum\limits_{ab\equiv j(mod~ M)}f[i][a]\cdot f[i][b]$$
时间复杂度\(O(m^2 log n)\)
考虑转换到对数上则可以化乘为加,而\(M\)为质数,原根\(g\)的\(g_0^{m-2}\)恰好对应\([1,m-1]\)
我们用这些代替数\(g^A\equiv a,g^B\equiv b,g^J\equiv j(mod~m)\)
相当于把\([1,m-1]\)通过这种方法映射到\([0,m-2]\),再进行数组初始化
\]
根据费马小定理\(g^a\equiv g^{a~mod~M-1}(mod~M)\),则:$$f[2*i][j]=\sum\limits_{g^{A+BmodM-1}= g^{Jmod M-1}}f[i][a]\cdot f[i][b]$$
\]
则化成了卷积的形式,而后面的取模,我们先正常做一下卷积,然后\(f[i][j]=f[i][j]+f[i][j+M-1]\)
Code
#include<bits/stdc++.h>
typedef int LL;
const LL Mod=1004535809,maxn=1e6+9,G=3;
inline LL Read(){
LL x(0),f(1); char c=getchar();
while(c<'0' || c>'9'){
if(c=='-') f=-1; c=getchar();
}
while(c>='0' && c<='9'){
x=(x<<3)+(x<<1)+c-'0'; c=getchar();
}return x*f;
}
LL n,m,g,x,num;
LL prime[maxn],r[maxn],c[maxn],d[maxn],pos[maxn],F[maxn],H[maxn];
inline LL Pow(LL base,LL b,LL mod){
LL sum(1);
while(b){
if(b&1) sum=1ll*sum*base%mod; base=1ll*base*base%mod; b>>=1;
}return sum;
}
inline LL Get_g(LL N){
LL p(--N),tot(0);
for(LL i=2;i*i<=N;++i){
if(N%i==0){
while(N%i==0) N/=i;
prime[++tot]=i;
}
}
if(N>1) prime[++tot]=N;
LL now(2);
while(true){
bool flag(false);
for(LL i=1;i<=tot;++i)
if(Pow(now,p/prime[i],p+1)==1){
flag=true;
break;
}
if(!flag) return now;
++now;
}
}
inline LL Init(LL N){
LL limit(1),len(0);
while(limit<N){
limit<<=1; ++len;
}
for(LL i=0;i<limit;++i) r[i]=(r[i>>1]>>1)|((i&1)<<len-1);
return limit;
}
inline void NTT(LL *a,LL limit,LL type,LL mod=Mod){
for(LL i=0;i<limit;++i) if(i<r[i]) std::swap(a[i],a[r[i]]);
for(LL mid=1;mid<limit;mid<<=1){
LL wn(Pow(G,(mod-1)/(mid<<1),mod));
if(type==-1) wn=Pow(wn,mod-2,mod);
for(LL R=mid<<1,j=0;j<limit;j+=R){
for(LL k=0,w=1;k<mid;++k,w=1ll*w*wn%mod){
LL x(a[j+k]),y(1ll*w*a[j+mid+k]%mod);
a[j+k]=1ll*(x+y)%mod;
a[j+mid+k]=1ll*(x-y+mod)%mod;
}
}
}
if(type==-1){
LL now(Pow(limit,mod-2,mod));
for(LL i=0;i<limit;++i) a[i]=1ll*a[i]*now%mod;
}
}
inline void Mul(LL *a,LL *b,LL limit,LL N,LL mod=Mod){
for(LL i=0;i<limit;++i) c[i]=a[i];
for(LL i=0;i<limit;++i) d[i]=b[i];
NTT(c,limit,1); NTT(d,limit,1);
for(LL i=0;i<limit;++i) c[i]=1ll*c[i]*d[i]%mod;
NTT(c,limit,-1);
for(LL i=0;i<N-1;++i) c[i]=1ll*(c[i]+c[i+N-1])%mod;
for(LL i=0;i<N-1;++i) a[i]=c[i];
}
int main(){
n=Read(); m=Read(); x=Read(); num=Read();
g=Get_g(m);
for(LL i=0;i<m-1;++i) pos[Pow(g,i,m)]=i;
for(LL i=1;i<=num;++i){
LL val(Read());
if(val) ++F[pos[val]];
}
H[pos[1]]=1;
LL limit(Init(2*m));
while(n){
if(n&1) Mul(H,F,limit,m); Mul(F,F,limit,m); n>>=1;
}
printf("%d\n",H[pos[x]]);
return 0;
}
[SDOI2015]序列统计(NTT+求原根)的更多相关文章
- 【BZOJ3992】[SDOI2015]序列统计 NTT+多项式快速幂
[BZOJ3992][SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属 ...
- BZOJ 3992: [SDOI2015]序列统计 NTT+快速幂
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1155 Solved: 532[Submit][Statu ...
- BZOJ3992: [SDOI2015]序列统计(NTT 原根 生成函数)
题意 题目链接 给出大小为\(S\)的集合,从中选出\(N\)个数,满足他们的乘积\(\% M = X\)的方案数 Sol 神仙题Orz 首先不难列出最裸的dp方程,设\(f[i][j]\)表示选了\ ...
- bzoj 3992: [SDOI2015]序列统计 NTT+原根
今天开始学习丧心病狂的多项式qaq...... . code: #include <bits/stdc++.h> #define ll long long #define setIO ...
- 【BZOJ】3992: [SDOI2015]序列统计 NTT+生成函数
[题意]给定一个[0,m-1]范围内的数字集合S,从中选择n个数字(可重复)构成序列.给定x,求序列所有数字乘积%m后为x的序列方案数%1004535809.1<=n<=10^9,3< ...
- bzoj 3992 [SDOI2015]序列统计——NTT(循环卷积&&快速幂)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3992 有转移次数.模M余数.方案数三个值,一看就是系数的地方放一个值.指数的地方放一个值.做 ...
- bzoj 3992 [SDOI2015] 序列统计 —— NTT (循环卷积+快速幂)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3992 (学习NTT:https://riteme.github.io/blog/2016-8 ...
- [BZOJ3992][SDOI2015]序列统计(DP+原根+NTT)
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1888 Solved: 898[Submit][Statu ...
- BZOJ 3992: [SDOI2015]序列统计 快速幂+NTT(离散对数下)
3992: [SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S ...
随机推荐
- 最新版Navicate破解激活
2019年5月5日激活成功 版本12.1.18 Navicat12.1下载地址 http://www.navicat.com.cn/download/navicat-premium有32位和64位,大 ...
- 30分钟用Restful ABAP Programming模型开发一个支持增删改查的Fiori应用
2016年时,Jerry曾经写过一系列关于SAP Fiori Smart Template(现在更名为Fiori Elements了)的博客,介绍了所谓的MDD开发方法论 - Metadata Dri ...
- 【前端开发】ES6知识点系统化梳理笔记
>ES6扩展: #Map和Set是es6标准新增的数据类型 ##Map是key-value(关键字-值),Map允许修改value,不允许修改key,Map支持下标操作 var m = new ...
- 基于FTP 的本地Yum服务器配置
服务器端 环境如下 Vmware14CentOS 7.6 192.168.20.81 server 192.168.20.81 client 1.配置yum源 mount /dev/cdrom /me ...
- websocket搭建的聊天室
在前后端数据交互的时候我们经常使用的是ajax,用的是传统的http协议,而http协议有个致命的缺点,就是请求一结束,连接就断开了, 我们为了保持这个链接的,通常会使用cookie,而自从h5出现w ...
- java.lang.AbstractMethodError: org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.isTypeMockable
[转]https://stackoverflow.com/questions/53539930/java-lang-abstractmethoderror-org-powermock-api-mock ...
- NodeJS开发博客(二) 接入数据库
1. mysql 数据库下载网址:https://dev.mysql.com/downloads/mysql/ 账号是 root 密码是 a1************ 网站账号是邮箱,密码是 Aa1* ...
- 用CSS 实现 非浮动元素的 水平居中/垂直居中/水平垂直居中
一.水平居中 (1)行内元素解决方案 只需要把行内元素包裹在一个属性display为block的父层元素中,并且把父层元素添加如下属性即可: .parent { text-align:center ...
- WebStorm 安装
官方下载地址:https://www.jetbrains.com/webstorm/ 下载 安装 等待.......... 安装完成........................ 开始使用(第一次 ...
- Django Forms的错误提示
1.error_messages={} 首先,在构建form表单时,可以用"error_messages={}"自定义错误信息,例如: # form.py 1 from djang ...