【bzoj3992】 SDOI2015—序列统计
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—序列统计的更多相关文章
- [BZOJ3992][SDOI2015]序列统计(DP+原根+NTT)
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1888 Solved: 898[Submit][Statu ...
- BZOJ3992: [SDOI2015]序列统计(NTT 原根 生成函数)
题意 题目链接 给出大小为\(S\)的集合,从中选出\(N\)个数,满足他们的乘积\(\% M = X\)的方案数 Sol 神仙题Orz 首先不难列出最裸的dp方程,设\(f[i][j]\)表示选了\ ...
- BZOJ3992: [SDOI2015]序列统计
Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S. 小C用这个生成器生成了许多这样的数列. ...
- 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− ...
- 【动态规划】bzoj3992 [Sdoi2015]序列统计 10分
#include<cstdio> using namespace std; #define MOD 1004535809 int a[8001],f[1001][101],n,m,x,S; ...
- 【NTT】bzoj3992: [SDOI2015]序列统计
板子题都差点不会了 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数 列,数列中的每个数都属于集合S.小C用这个生成器生 ...
- BZOJ3992 [SDOI2015]序列统计 【生成函数 + 多项式快速幂】
题目 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数 列,数列中的每个数都属于集合S.小C用这个生成器生成了许多这样的数列.但是小C有一个问题 ...
- 【BZOJ3992】[SDOI2015]序列统计 NTT+多项式快速幂
[BZOJ3992][SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属 ...
- BZOJ 3992: [SDOI2015]序列统计 [快速数论变换 生成函数 离散对数]
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1017 Solved: 466[Submit][Statu ...
- [SDOI2015]序列统计
[SDOI2015]序列统计 标签: NTT 快速幂 Description 给你一个模m意义下的数集,需要用这个数集生成一个数列,使得这个数列在的乘积为x. 问方案数模\(1004535809\). ...
随机推荐
- 使用BAPI批量修改采购信息记录的税率
业务方面提出需求:由于国家税率从5月份开始16%更改为13%.要求开发一个批量修改采购信息记录税率的功能. 税代码就是税率,J2代表13% 这个需求在ME13里面就可以单个修改,所以可以用BDC,但后 ...
- 2017-2018-2 20155203《网络对抗技术》Exp9 :Web安全基础
实践过程记录 - SQL Injection(Webgoat 8.0&Webgoat7.0) 1. SQL Injection(Webgoat 8.0). 这一部分很基础,是简单的sql注入, ...
- FAT32文件系统学习(2) —— FAT表
1.题外话 在继续本文学习FAT32文件系统之前,先来插入一点别的话题.我们都知道U盘有一个属性是容量,就拿笔者的U盘为例,笔者手上的U盘是金士顿的DataTraveler G3 4GB的一个U盘.电 ...
- Voronoi图与Delaunay三角剖分
详情请见[ZJOI2018]保镖 题解随笔 - 99 文章 - 0 评论 - 112
- libgdx学习记录19——图片动态打包PixmapPacker
libgdx中,opengl 1.x要求图片长宽必须为2的整次幂,一般有如下解决方法 1. 将opengl 1.x改为opengl 2.0.(libgdx 1.0版本后不支持1.x,当然不存在这个问题 ...
- Neo4j 第四篇:使用C#更新和查询Neo4j
本文使用的IDE是Visual Studio 2015 ,驱动程序是Neo4j官方的最新版本:Neo4j Driver 1.3.0 ,创建的类库工程(Project)要求安装 .NET Framewo ...
- Java英文单词Java基础常见英语词汇
Java英文单词Java基础常见英语词汇(共70个) ...
- Frida----安装
介绍 它是本机应用程序的 Greasemonkey,或者更多技术术语,它是一个动态代码检测工具包.它允许您将JavaScript或您自己的库的片段注入Windows,macOS,GNU / Linux ...
- 转 ssh-keygen 的 详解
为了让两个linux机器之间使用ssh不需要用户名和密码.所以采用了数字签名RSA或者DSA来完成这个操作. 模型分析 假设 A (192.168.20.59)为客户机器,B(192.168.20.6 ...
- 基于Shader实现的UGUI描边解决方案
基于Shader实现的UGUI描边解决方案 前言 大扎好,我系狗猥.当大家都以为我鸽了的时候,我又出现了,这也是一种鸽.创业两年失败后归来,今天想给大家分享一个我最近研究出来的好康的,比游戏还刺激,还 ...