[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 ...
随机推荐
- Spring中bean的管理
Spring 中常见的容器 我们知道spring容器就是spring中bean的驻留场所.spring容器并不是只有一个.spring自带了多个容器实现,可以归为两种不同的类型:bean工厂和应用上下 ...
- 这个一个对ES6多个异步处理的并发继发思想的总结和理解
1.首先我们需要理解的是js中for循环.forEach循环.map循环的一些差异性,直接说了为后面说到的提供一些依据 1.1 for循环最基本,也是最容易理解的. 1.2 forEach和map用法 ...
- ES6中 对字符串增强
在曾经,我们只能用A.indexof(B)来判断A中是否含有B字符串: 现在在ES6中 有了: includes(), startswith(),endswith() reapt()重复次数: 输出 ...
- nginx 请求限制和访问控制
请求限制 限制主要有两种类型: 连接频率限制: limit_conn_module 请求频率限制: limit_req_module HTTP协议的连接与请求 HTTP协议是基于TCP的,如果要完成一 ...
- DBCP连接池原理分析(转载)
DBCP连接池介绍 ----------------------------- 目前 DBCP 有两个版本分别是 1.3 和 1.4. DBCP 1.3 版本需要运行于 JDK 1.4-1.5 ,支持 ...
- Hive笔记及配置
Hive 基于Hadoop的数据仓库工具: 将结构化的数据文件,映射为一张表,并提供类SQL查询功能: 本质:将HQL转化为MapReduce程序: Hive处理的数据存储在HDFS: Hive分析数 ...
- docker 部署oracle
Oracle数据库服务器Docker映像文档 Oracle Database Server 12c R2是行业领先的关系数据库服务器.Oracle数据库服务器Docker映像包含在Oracle Lin ...
- 微信小程序 之wxml保留小数点后两位数的方法及转化为字符串的方法
原理:wxml中不能直接使用较高级的js语法,如‘.toFixed’,‘toString()’,但可以通过引入wxs模块实现效果 1.新建`filter.wxs` var filters = { ...
- Android笔记(十七) Android中的Service
定义和用途 Service是Android的四大组件之一,一直在后台运行,没有用户界面.Service组件通常用于为其他组件提供后台服务或者监控其他组件的运行状态,例如播放音乐.记录地理位置,监听用户 ...
- http接口测试工具-Advanced-REST-client
非常好用的http接口测试工具 相信作为一个java开发人员,大家或多或少的要写或者接触一些http接口.而当我们需要本地调试接口常常会因为没有一款好用的工具而烦恼.今天要给大家介绍一款非常好用.实用 ...