bzoj 3992: [SDOI2015]序列统计【原根+生成函数+NTT+快速幂】
还是没有理解透原根……题目提示其实挺明显的,M是质数,然后1<=x<=M-1
这种计数就容易想到生成函数,但是生成函数是加法,而这里是乘法,所以要想办法变成加法
首先因为0和任何数乘都是0,和其他数规则不相符,所以不考虑(答案也没让求)
然后看原根的性质,设g是M的原根,那么\( g^i%M 0<=i<M-1 \)就是1~M-1的不重集合,所以可以把乘法变成原根指数的加法,这样就变成多项式乘法了,可以用NTT优化
然后n非常大,所以使用快速幂进行多项式乘法
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=20005,mod=1004535809,g=3;
int n,m,x,k,s[N],d=2,id[N],lm,bt,re[N];
long long a[N],c[N],r[N];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void jia(long long &x,long long &y)
{
x+=y;
x>=mod?x-=mod:0;
}
long long ksm(long long a,long long b,int mod)
{
long long r=1;
while(b)
{
if(b&1)
r=r*a%mod;
a=a*a%mod;
b>>=1;
}
return r;
}
void dft(long long a[],int f)
{
for(int i=0;i<lm;i++)
if(i<re[i])
swap(a[i],a[re[i]]);
for(int i=1;i<lm;i<<=1)
{
long long wi=ksm(g,(mod-1)/(2*i),mod);
if(f==-1)
wi=ksm(wi,mod-2,mod);
for(int k=0;k<lm;k+=(i<<1))
{
long long w=1,x,y;
for(int j=0;j<i;j++)
{
x=a[j+k],y=1ll*w*a[i+j+k]%mod;
a[j+k]=((x+y)%mod+mod)%mod,a[i+j+k]=((x-y)%mod+mod)%mod;
w=w*wi%mod;
}
}
}
if(f==-1)
{
long long inv=ksm(lm,mod-2,mod);
for(int i=0;i<lm;i++)
a[i]=a[i]*inv%mod;
}
}
void ntt(long long a[],long long b[])
{
for(int i=0;i<lm;i++)
c[i]=b[i];
dft(a,1);
dft(c,1);
for(int i=0;i<lm;i++)
a[i]=a[i]*c[i]%mod;
dft(a,-1);
for(int i=m-1;i<lm;i++)
jia(a[i%(m-1)],a[i]),a[i]=0;
// for(int i=0;i<lm;i++)
// cerr<<a[i]<<" ";cerr<<endl;
}
int main()
{
n=read()-1,m=read(),x=read(),k=read();
for(int i=1;i<=k;i++)
s[i]=read();
for(bool fl=0;!fl;d++)
{
fl=1;
for(int i=1;i<m-1;i++)
if(ksm(d,i,m)==1)
{
fl=0;
break;
}
if(ksm(d,m-1,m)!=1)
fl=0;
if(fl)
break;
}
for(int i=0;i<m-1;i++)
id[ksm(d,i,m)]=i;//,cerr<<rl[i]<<" "<<i<<endl;
for(int i=1;i<=k;i++)
if(s[i])
a[id[s[i]]]++,r[id[s[i]]]++;
for(bt=0;(1<<bt)<=2*m;bt++);
lm=(1<<bt);
for(int i=0;i<lm;i++)
re[i]=(re[i>>1]>>1)|((i&1)<<(bt-1));
while(n)
{
if(n&1)
ntt(r,a);
ntt(a,a);
n>>=1;
}
printf("%lld\n",r[id[x]]);
return 0;
}
bzoj 3992: [SDOI2015]序列统计【原根+生成函数+NTT+快速幂】的更多相关文章
- 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]序列统计 【生成函数 + 多项式快速幂】
题目 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数 列,数列中的每个数都属于集合S.小C用这个生成器生成了许多这样的数列.但是小C有一个问题 ...
- BZOJ 3992: [SDOI2015]序列统计 [快速数论变换 生成函数 离散对数]
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1017 Solved: 466[Submit][Statu ...
- BZOJ 3992: [SDOI2015]序列统计 NTT+快速幂
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1155 Solved: 532[Submit][Statu ...
- BZOJ 3992: [SDOI2015]序列统计 快速幂+NTT(离散对数下)
3992: [SDOI2015]序列统计 Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S ...
- [BZOJ 3992][SDOI2015]序列统计
3992: [SDOI2015]序列统计 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 2275 Solved: 1090[Submit][Stat ...
- BZOJ.3992.[SDOI2015]序列统计(DP NTT 原根)
题目链接 \(Description\) 给定\(n,m,x\)和集合\(S\).求\(\prod_{i=1}^na_i\equiv x\ (mod\ m)\)的方案数.其中\(a_i\in S\). ...
- 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 ...
随机推荐
- Android——坐标系及转化
一.坐标系 Android应用层坐标系原点在左上角,坐标范围(0,0)——(width,height). Android底层坐标系原点在屏幕中央,坐标范围(-1000,,1000)——(1000,10 ...
- ADO.NET 对数据操作 以及如何通过C# 事务批量导入数据
ADO.NET 对数据操作 以及如何通过C# 事务批量导入数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ...
- 作为iOS程序员,最核心的60%能力有哪些?
作为iOS程序员,最核心的60%能力有哪些? 一个合格的iOS程序员需要掌握多少核心技能?你和专业的开发工程师的差距有多大?你现在的水平能开发一个功能完整性能高效的iOS APP吗?一起来看看下面 ...
- iOS开发之---判断是否是手机号
iOS开发之---判断是否是手机号
- ubuntu 系统启动时找不到根文件系统
报出的错误大概为: Alert! /dev/disk/by-uuid/ ....... does not exist 最后进入了 initramdiskfs 的命令行终端 . 输入 blkid 命令却 ...
- Apache Qpid CPP的编译与安装
单机Broker部署(windows/linux) 在Windows/Linux上部署QPID Broker的方法. Windows 需要预先准备的文件和程序 qpid-cpp-0.32.tar.gz ...
- Spring Boot JPA 连接数据库
本文将介绍怎样在Spring Boot project中加入JPA作为持久化方式. 改动 pom.xml 依赖 与上一篇介绍的 jdbc 不同的是 spring-boot-starter-jdbc 改 ...
- HDU 6078 Wavel Sequence 树状数组优化DP
Wavel Sequence Problem Description Have you ever seen the wave? It's a wonderful view of nature. Lit ...
- monitor and move the log content to our big data system
Apache Flume HDFS Sink Tutorial | HowToProgram https://howtoprogram.xyz/2016/08/01/apache-flume-hdfs ...
- 二阶段 三阶段 提交 Paxos
关于分布式事务.两阶段提交协议.三阶提交协议 - 文章 - 伯乐在线 http://blog.jobbole.com/95632/