题目


分析

首先朴素dp方程

设\(dp[i][j]\)表示\(i\)个数的数列乘积为\(j\)的方案

那么\(dp[i][j*a[k]\bmod m]=itself+dp[i-1][j]\)

这可以用矩阵乘法优化到\(O(m^3log_2n)\),然而考场真的不想写

其实这个方程不明显,考虑到\(n\)超级大,不是矩阵乘法就是快速幂(推测)

能不能用2的多少次方拼凑出长度为\(n\)的数列

刚刚的方程可以变为$$dp[2i][t]=\sum_{xy\bmod m==t}dp[i][x]+dp[i][y]$$

那乘法怎么办呢,用原根把乘法变成加法,那就可以用NTT做了

至于原根我不好解释,但是原根会比较小,

具体做法就是\(g^k\neq 1(k|p-1)\)那么\(g\)就是\(p\)的一个原根(准确来说应该是\(\varphi(p)\),但是这里是质数)


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int mod=1004535809,invG=334845270,N=8011;
int n,r[N<<2],inv1,inv2,m,G,F[N<<2],Ans[N<<2],fi[N],KsM,S,X;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline signed ksm(int x,int y,int p){
rr int ans=1;
for (;y;y>>=1,x=1ll*x*x%p)
if (y&1) ans=1ll*ans*x%p;
return ans;
}
inline signed Getroot(int p){
for (rr int g=2;;++g){
rr bool flag=1;
for (rr int i=2;i*i<p;++i)
if ((p-1)%i==0&&(ksm(g,i,p)==1||ksm(g,(p-1)/i,p)==1)) flag=0;
if (flag) return g;
}
}
inline signed mo(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline void ntt(int *f,int op){
for (rr int i=0;i<n;++i)
if (i<r[i]) swap(f[i],f[r[i]]);
for (rr int p=2;p<=n;p<<=1){
rr int len=p>>1,w=ksm(op==1?3:invG,(mod-1)/p,mod);
for (rr int i=0;i<n;i+=p)
for (rr int j=i,t=1;j<i+len;++j,t=1ll*t*w%mod){
rr int z=1ll*f[len+j]*t%mod;
f[len+j]=mo(f[j],mod-z),f[j]=mo(f[j],z);
}
}
}
inline void cheng(int *c,int *a,int *b){
rr int f[N<<2],g[N<<2],C[N<<2];
for (rr int i=0;i<n;++i) f[i]=a[i],g[i]=b[i];
ntt(f,1),ntt(g,1); for (rr int i=0;i<n;++i) f[i]=1ll*f[i]*g[i]%mod;
ntt(f,-1); for (rr int i=0;i<n;++i) f[i]=1ll*f[i]*inv1%mod;
for (rr int i=0;i<m-1;++i) C[i]=mo(f[i],f[i+m-1]);
for (rr int i=0;i<n;++i) c[i]=C[i];
}
signed main(){
KsM=iut(),m=iut(),X=iut(),S=iut(),G=Getroot(m),fi[1]=0;
for (rr int i=1,t=1;i<m-1;++i) fi[t=t*G%m]=i;
for (rr int i=1;i<=S;++i){
rr int t=iut();
if (t) ++F[fi[t]];
}
Ans[0]=1;
for (n=1;n<=2*m-2;n<<=1); inv1=ksm(n,mod-2,mod);
for (rr int i=0;i<n;++i) r[i]=(r[i>>1]>>1)|((i&1)?n>>1:0);
for (;KsM;KsM>>=1,cheng(F,F,F)) if (KsM&1) cheng(Ans,Ans,F);
printf("%d",Ans[fi[X]]);
return 0;
}

#NTT,原根#洛谷 3321 JZOJ 4051 [SDOI2015]序列统计的更多相关文章

  1. 【洛谷3321_BZOJ3992】[SDOI2015]序列统计(原根_多项式)

    题目: 洛谷3321 分析: 一个转化思路比较神(典型?)的题-- 一个比较显然的\(O(n^3)\)暴力是用\(f[i][j]\)表示选了\(i\)个数,当前积在模\(m\)意义下为\(j\)的方案 ...

  2. [BZOJ3992][SDOI2015]序列统计(DP+原根+NTT)

    3992: [SDOI2015]序列统计 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1888  Solved: 898[Submit][Statu ...

  3. [SDOI2015]序列统计(NTT+求原根)

    题目 [SDOI2015]序列统计 挺好的题!!! 做法 \(f[i][j]\)为第\(i\)个数前缀积在模\(M\)意义下为\(j\) 显然是可以快速幂的:\[f[2*i][j]=\sum\limi ...

  4. 【BZOJ3992】[SDOI2015]序列统计 NTT+多项式快速幂

    [BZOJ3992][SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属 ...

  5. BZOJ 3992: [SDOI2015]序列统计 NTT+快速幂

    3992: [SDOI2015]序列统计 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1155  Solved: 532[Submit][Statu ...

  6. BZOJ 3992: [SDOI2015]序列统计 快速幂+NTT(离散对数下)

    3992: [SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S ...

  7. 【LG3321】[SDOI2015]序列统计

    [LG3321][SDOI2015]序列统计 题面 洛谷 题解 前置芝士:原根 我们先看一下对于一个数\(p\),它的原根\(g\)有什么性质(好像就是定义): \(g^0\%p,g^1\%p,g^2 ...

  8. [SDOI2015]序列统计

    [SDOI2015]序列统计 标签: NTT 快速幂 Description 给你一个模m意义下的数集,需要用这个数集生成一个数列,使得这个数列在的乘积为x. 问方案数模\(1004535809\). ...

  9. 3992: [SDOI2015]序列统计

    3992: [SDOI2015]序列统计 链接 分析: 给定一个集和s,求多少个长度为n的序列,满足序列中每个数都属于s,并且所有数的乘积模m等于x. 设$f=\sum\limits_{i=0}^{n ...

  10. [BZOJ 3992][SDOI2015]序列统计

    3992: [SDOI2015]序列统计 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 2275  Solved: 1090[Submit][Stat ...

随机推荐

  1. 【Android 逆向】【攻防世界】easy-so

    1. apk安装到手机,随便输入点内容,提示错误 2. jadx打开apk btn.setOnClickListener(new View.OnClickListener() { // from cl ...

  2. SQL Server 连接数据库报错 (ObjectExplorer)

    报错信息 无法访问数据库 ReportServer. (ObjectExplorer) 具体错误信息: 程序位置: 在 Microsoft.SqlServer.Management.UI.VSInte ...

  3. 【Azure API 管理】APIM服务资源删除后,为什么不能马上创建相同名称的APIM服务呢?

    问题描述 使用Azure APIM服务,在删除旧资源准备新建相同名称的新APIM服务时,尝试多次都是出现"指定的服务名称已正在使用"错误.但实际上同名称的服务已经被删除.为什么多次 ...

  4. 【Azure Fabric Service】Service Fabric 遇见错误信息记录 - The process/container terminated with exit code:2148734499

    问题描述 Service Fabric 在升级 Application 过程中,发布了新的代码后,启动应用中遇见了如下错误: Error message: System.Hosting' report ...

  5. 3.1蓝桥杯每日知识点,全排列permutation

    next_permutation()函数 适用于生成当前序列的下一个排列 如果存在下一个排列,则将当前序列更改为下一个排列,并返回true 如果当前序列已经是最后一个排列,则将序列更改为第一个排列,并 ...

  6. RocketMQ(11) 消息重试机制和死信队列

    七.消息发送重试机制 1 说明 Producer对发送失败的消息进行重新发送的机制,称为消息发送重试机制,也称为消息重投机制. 对于消息重投,需要注意以下几点: 生产者在发送消息时,若采用同步或异步发 ...

  7. 深入理解与应用CSS clip-path 属性

    clip-path clip-path是什么 clip-path 是一个CSS属性,允许开发者创建一个剪切区域,从而决定元素的哪些部分可见,哪些部分会被隐藏.通过定义这个剪切路径(clipping p ...

  8. 函数指针 int (*add)( )

    原文 首先它是一个指针,一个指向函数的指针,在内存空间中存放的是函数的地址: int Add(int x,int y) { return x+y; } int main() { printf(&quo ...

  9. 摆脱鼠标系列 - 百度搜索 - 火柴 - 快捷键 Ctrl两次

    摆脱鼠标系列 - 百度搜索 - 火柴 - 快捷键 Ctrl两次 有两款软件 utools 和 火柴,试用后觉得火柴符合试用功能 这里只用网络搜索 其他功能均不用 搜索用双核浏览器 因为用的老的chro ...

  10. InputNumber 不能输入点 viewDesign 需求是 只能是整数

    <InputNumber ref="xxxRef" v-model="xxx" :disabled="xxx" style=" ...