http://www.lydsy.com/JudgeOnline/problem.php?id=3992 (题目链接)

题意

  集合${S}$中有若干个不超过${m}$的非负整数,问由这些数组成一个长度${n}$的序列,使序列中的数的乘积对${m}$取模正好等于${x}$,问存在多少方案。

Solution

  好神的题。算法还是要多复习,我连${NTT}$都忘记怎么写了T_T

  这还是我的第一发原根→_→。

  一个数如果有原根,那么它会有很多原根,所以如果对时间没有特殊限制,我们枚举${rt=2~~to~~inf}$,然后判断是否存在${t<m-1}$使${rt^t=1}$。虽然我并不知道为什么可以那样check。。

  我们可以很简单的列出dp方程${f_{i,j}}$表示,已经放到了第${i}$个数,它们的乘积是${j}$的方案数。转移也就很显然了:$${f[i][j]=\sum_{k=1}^{m-1}f_{i-1,j*inv[k]}}$$

  复杂度${O(nm^2)}$,于是我们就可以获得10分的高分,是不是很良心啊。

  考虑这个东西怎么优化,我们把每一个${j}$都写成${m}$的原根的几次方,然后乘就变成加辣,然后我们就可以卷积辣。

  然后你发现${n}$有${10^9}$,我们快速幂一波,然后就AC辣。

细节

  一开始没想清没注意到还是循环卷积卧槽T_T

代码

// bzoj3992
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#define LL long long
#define inf (1ll<<30)
#define MOD 1004535809
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=20010;
int f[maxn],g[maxn],rev[maxn],vis[maxn];
int n,m,rt,S,X,N,L; int power(int a,int b,int c) {
int res=1;
while (b) {
if (b&1) res=(LL)res*a%c;
b>>=1;a=(LL)a*a%c;
}
return res;
}
void root(int p) {
if (p==2) {rt=1;return;}
for (rt=2;;rt++) {
int flag=1;
for (int i=2;i*i<p;i++)
if (power(rt,(p-1)/i,p)==1) {flag=0;break;}
if (flag) break;
}
}
namespace NTT {
LL A[maxn],B[maxn];
void NTT(LL *a,int f) {
for (int i=0;i<N;i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
for (int i=1;i<N;i<<=1) {
LL gn=power(3,(MOD-1)/(i<<1),MOD);
for (int p=i<<1,j=0;j<N;j+=p) {
LL g=1;
for (int k=0;k<i;k++,(g*=gn)%=MOD) {
LL x=a[k+j],y=g*a[k+j+i]%MOD;
a[k+j]=(x+y)%MOD,a[k+j+i]=(x-y+MOD)%MOD;
}
}
}
if (f==-1) reverse(a+1,a+N);
}
void Init(int *a,int *b) {
for (int i=0;i<N;i++) A[i]=a[i],B[i]=b[i];
NTT(A,1);NTT(B,1);
for (int i=0;i<N;i++) (A[i]*=B[i])%=MOD;
NTT(A,-1);
LL ev=power(N,MOD-2,MOD);
for (int i=0;i<N;i++) (A[i]*=ev)%=MOD;
for (int i=0;i<m-1;i++) a[i]=(A[i]+A[i+m-1])%MOD;
}
}
using namespace NTT; int main() {
scanf("%d%d%d%d",&n,&m,&X,&S);
root(m);
for (int x,i=1;i<=S;i++) scanf("%d",&x),vis[x]=1;
for (int p=1,i=0;i<m-1;i++,(p*=rt)%=m) if (vis[p]) f[i]=1;
for (N=1,L=-1;N<(m-1)*2;N<<=1) L++;
for (int i=0;i<N;i++) rev[i]=(rev[i>>1]>>1) | ((i&1)<<L);
g[0]=1;
while (n) {
if (n&1) Init(g,f);
n>>=1;Init(f,f);
}
for (int i=0,p=1;i<m-1;i++,(p*=rt)%=m)
if (p==X) {printf("%d",g[i]);break;}
return 0;
}

【bzoj3992】 SDOI2015—序列统计的更多相关文章

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

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

  2. BZOJ3992: [SDOI2015]序列统计(NTT 原根 生成函数)

    题意 题目链接 给出大小为\(S\)的集合,从中选出\(N\)个数,满足他们的乘积\(\% M = X\)的方案数 Sol 神仙题Orz 首先不难列出最裸的dp方程,设\(f[i][j]\)表示选了\ ...

  3. BZOJ3992: [SDOI2015]序列统计

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

  4. 2018.12.31 bzoj3992: [SDOI2015]序列统计(生成函数+ntt+快速幂)

    传送门 生成函数简单题. 题意:给出一个集合A={a1,a2,...as}A=\{a_1,a_2,...a_s\}A={a1​,a2​,...as​},所有数都在[0,m−1][0,m-1][0,m− ...

  5. 【动态规划】bzoj3992 [Sdoi2015]序列统计 10分

    #include<cstdio> using namespace std; #define MOD 1004535809 int a[8001],f[1001][101],n,m,x,S; ...

  6. 【NTT】bzoj3992: [SDOI2015]序列统计

    板子题都差点不会了 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数 列,数列中的每个数都属于集合S.小C用这个生成器生 ...

  7. BZOJ3992 [SDOI2015]序列统计 【生成函数 + 多项式快速幂】

    题目 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数 列,数列中的每个数都属于集合S.小C用这个生成器生成了许多这样的数列.但是小C有一个问题 ...

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

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

  9. BZOJ 3992: [SDOI2015]序列统计 [快速数论变换 生成函数 离散对数]

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

  10. [SDOI2015]序列统计

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

随机推荐

  1. SAP查询TABLE对应的文本表

    SAP 取数时,通常配置项,需要取对应的文本描述,一般在配置表后加个T,就可以找到描述对应的表名. 但有时也有不符合这个规则的,例如生产订单类型数据表 T003O. 表名加T后并不存T003OT. 这 ...

  2. 20155207 EXP7 EXP8 EXP9 实验补交

    20155207 EXP7 EXP8 EXP9 实验补交 20155207 EXP7 网络欺诈技术防范 20155207 EXP8 Web基础 20155207 <网络对抗> Exp9 W ...

  3. Remote 桌面的win2003 servre端设定

    Microsoft Windows [版本 5.2.3790](C) 版权所有 1985-2003 Microsoft Corp. C:\Documents and Settings\Administ ...

  4. Caffe 深度学习框架上手教程

    Caffe 深度学习框架上手教程   blink 15年1月   Caffe (CNN, deep learning) 介绍 Caffe -----------Convolution Architec ...

  5. CF 55 D. Beautiful numbers

    D. Beautiful numbers 链接 题意: 求[L,R]中多少个数字可以整除它们的每一位上的数字. 分析: 要求模一些数字等于0等价于模它们的lcm等于0,所以可以记录当前出现的数字的lc ...

  6. R语言学习 第三篇:数据框

    数据框(data.frame)是最常用的数据结构,用于存储二维表(即关系表)的数据,每一列存储的数据类型必须相同,不同数据列的数据类型可以相同,也可以不同,但是每列的行数(长度)必须相同.数据框的每列 ...

  7. 在Windows商店应用中使用浅色主题

    在开发商店应用时会遇到这样的情况,设计师给我们的设计是浅色背景/深色文本,而商店应用默认是深色背景/浅色文本.那我们需要在每个页面去显式声明背景色和前景色吗,这显然是不理想的.这时就需要设置应用的主题 ...

  8. java实现基于关键字的文件夹(文件)的搜索、文件夹(文件)的复制、删除

    最近在做一个项目,需要实现这几项功能,上网查了很多资料,自己研究了好几天终于实现了,现在与大家分享一下. 一.JAVA实现文件夹的搜索   在百度搜索N个技术文章,从哪些大牛们共享的资料中终于写出了我 ...

  9. dokuwiki编辑器修改-color插件-添加按钮

    需求 dokuwiki的编辑工具栏是以 MediaWiki 的为基础发展来的. 在它的编辑器color插件的颜色按钮中,我想添加新的按钮功能.如红色字体黄色背景的修饰,类似于涂中文字强调的意思. 步骤 ...

  10. 广州区块链系统or积分联盟

    区块链技术开发至今已有十年,从概念的现世到如今初步应用,区块链开发公司在各个领域开始发光发热,很多人都想参与其中,通过区块链开发实现企业转型来适应未来市场,也有一些初创者希望借此实现创业意图,但在诸多 ...