还是没有理解透原根……题目提示其实挺明显的,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+快速幂】的更多相关文章

  1. 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− ...

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

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

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

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

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

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

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

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

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

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

  7. BZOJ.3992.[SDOI2015]序列统计(DP NTT 原根)

    题目链接 \(Description\) 给定\(n,m,x\)和集合\(S\).求\(\prod_{i=1}^na_i\equiv x\ (mod\ m)\)的方案数.其中\(a_i\in S\). ...

  8. bzoj 3992 [SDOI2015]序列统计——NTT(循环卷积&&快速幂)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3992 有转移次数.模M余数.方案数三个值,一看就是系数的地方放一个值.指数的地方放一个值.做 ...

  9. bzoj 3992 [SDOI2015] 序列统计 —— NTT (循环卷积+快速幂)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3992 (学习NTT:https://riteme.github.io/blog/2016-8 ...

随机推荐

  1. Node.js机制及原理理解初步

    http://blog.csdn.net/leftfist/article/details/41891407 一.node.js优缺点 node.js是单线程. 好处就是 1)简单 2)高性能,避免了 ...

  2. MAC上Nuclide的安装

    MAC上Nuclide的安装 本文版权归作者全部,如需转载请联系孟祥月 CSDN博客:http://blog.csdn.net/mengxiangyue 独立博客:http://mengxiangyu ...

  3. c程序设计语言第一章1

    1,c程序都是由函数和变量组成的. 练习1.6验证布尔表达式getchar()!= EOF的取值是0还是1 答: #include <stdio.h> #include <stdli ...

  4. 互斥锁和条件变量(pthread)相关函数

    互斥锁 #include <pthread.h> // 若成功返回0,出错返回正的Exxx值 // mptr通常被初始化为PTHREAD_MUTEX_INITIALIZER int pth ...

  5. Android图表AChartEngine

    很多时候项目中我们需要对一些统计数据进行绘制表格,更多直观查看报表分析结果.基本有以下几种方法: 1:可以进行android api进行draw这样的话,效率比较低 2:使用开源绘表引擎,这样效率比较 ...

  6. 格式转换至yuv422转 yuv420

    //pYUV为422,yuv为420 /*ok! * brief:pyuv is yuv422sp srcIn, and yuv is yuv420p desOut  */ int YUV422To4 ...

  7. rtsp 播放器

    http://blog.csdn.net/niu_gao/article/details/7753672 /********************************************** ...

  8. Tomcat 安装与配置规范

    Tomcat 安装 演示版本:8.5.32 安装版 JDK推荐版本:jdk1.8 下载地址:https://tomcat.apache.org/download-80.cgi 安装教程 注意:tomc ...

  9. 如何查看Java进程并获取进程ID?

    1. 在 LINUX 命令平台输入 1-2 个字符后按 Tab 键会自动补全后面的部分(前提是要有这个东西,例如在装了 tomcat 的前提下, 输入 tomcat 的 to 按 tab).2. ps ...

  10. lc.exe 已退出 代码为 -1

    地址:http://jingyan.baidu.com/article/91f5db1bd0ace31c7f05e321.html