题目大意

  有一个集合\(s\),里面的每个数都\(\geq0\)且\(<m\)。

  问有多少个长度为\(n\)的数列满足这个数列所有数的乘积模\(m\)为\(x\)。答案模\(1004535809\)。

  \(n\leq {10}^9,m\leq 8000\)且\(m\)是质数。

题解

  先求出\(m\)的原根\(g\),这样\(1\)~\(m-1\)中的每个数都能被表示成\(g\)的幂。

  因为\(g^ig^j=g^{i+j}\),这样就可以把乘积转成和,问题转化为问有多少个长度为\(n\)的数列满足这个数列所有数的和模\(m-1\)为\(y\),\(f_{i+1,j}=\sum f_{i,k}f_{i,j-k}\)。因为模数是NTT模数,原根为\(3\),所以可以用NTT优化。

  ln&exp好像也可以做。

  时间复杂度:\(O(m\log m\log n)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int m;
ll p=1004535809;
int g;
int len=16384;
ll a[100010];
ll b[100010];
ll w1[100010];
ll w2[100010];
int rev[100010];
int c[10010];
ll fp(ll a,ll b)
{
ll s=1;
while(b)
{
if(b&1)
s=s*a%p;
a=a*a%p;
b>>=1;
}
return s;
}
int check(int x)
{
int s=1;
int i;
for(i=1;i<=m-2;i++)
{
s=s*x%m;
if(s==1)
return 0;
}
return 1;
}
void ntt(ll *a,int t)
{
int i,j,k;
ll u,v,w,wn;
for(i=0;i<len;i++)
if(rev[i]<i)
swap(a[i],a[rev[i]]);
for(i=2;i<=len;i<<=1)
{
wn=(t==1?w1[i]:w2[i]);
for(j=0;j<len;j+=i)
{
w=1;
for(k=j;k<j+i/2;k++)
{
u=a[k];
v=a[k+i/2]*w%p;
a[k]=(u+v)%p;
a[k+i/2]=(u-v+p)%p;
w=w*wn%p;
}
}
}
if(t==-1)
{
ll inv=fp(len,p-2);
for(i=0;i<len;i++)
a[i]=a[i]*inv%p;
}
}
void fp(int n)
{
int i;
while(n)
{
ntt(a,1);
if(n&1)
{
ntt(b,1);
for(i=0;i<len;i++)
b[i]=b[i]*a[i]%p;
ntt(b,-1);
for(i=m;i<len;i++)
{
b[i%m]=(b[i%m]+b[i])%p;
b[i]=0;
}
}
for(i=0;i<len;i++)
a[i]=a[i]*a[i]%p;
ntt(a,-1);
for(i=m;i<len;i++)
{
a[i%m]=(a[i%m]+a[i])%p;
a[i]=0;
}
n>>=1;
}
}
int main()
{
int n,x,u;
scanf("%d%d%d%d",&n,&m,&x,&u);
int i;
for(i=1;i<m;i++)
if(check(i))
g=i;
rev[0]=0;
for(i=1;i<len;i++)
rev[i]=(rev[i/2]>>1)|(i&1?len>>1:0);
for(i=2;i<=len;i<<=1)
{
w1[i]=fp(3,(p-1)/i);
w2[i]=fp(w1[i],p-2);
}
int s=1;
for(i=0;i<=m-2;i++)
{
c[s]=i;
s=s*g%m;
}
int v;
memset(a,0,sizeof a);
memset(b,0,sizeof b);
b[0]=1;
for(i=1;i<=u;i++)
{
scanf("%d",&v);
if(!v)
continue;
a[c[v]]++;
}
m--;
fp(n);
printf("%lld\n",b[c[x]]);
return 0;
}

【BZOJ3992】【SDOI2015】序列统计 原根 NTT的更多相关文章

  1. 【bzoj3992】[SDOI2015]序列统计 原根+NTT

    题目描述 求长度为 $n$ 的序列,每个数都是 $|S|$ 中的某一个,所有数的乘积模 $m$ 等于 $x$ 的序列数目模1004535809的值. 输入 一行,四个整数,N.M.x.|S|,其中|S ...

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

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

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

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

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

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

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

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

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

  7. BZOJ3992: [SDOI2015]序列统计

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

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

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

  9. 洛谷P3321 [SDOI2015]序列统计(NTT)

    传送门 题意:$a_i\in S$,求$\prod_{i=1}^na_i\equiv x\pmod{m}$的方案数 这题目太珂怕了……数学渣渣有点害怕……kelin大佬TQL 设$f[i][j]$表示 ...

随机推荐

  1. centos开启ftp服务的步骤

    1.安装vsftpd sudo yum install vsftpd -y 2.启动ftp服务 service vsftpd start 3.  加入开机启动 chkconfig vsftpd on ...

  2. Python里面如何拷贝一个对象

    1.赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个. In [168]: a Out[168]: [1, 2, 3] In [169]: b=a In [170]: a ...

  3. snappy

    Snappy 是一个 C++ 的用来压缩和解压缩的开发包.其目标不是最大限度压缩或者兼容其他压缩格式,而是旨在提供高速压缩速度和合理的压缩率.Snappy 比 zlib 更快,但文件相对要大 % 到 ...

  4. PAT L2-009 抢红包

    https://pintia.cn/problem-sets/994805046380707840/problems/994805066890854400 没有人没抢过红包吧…… 这里给出N个人之间互 ...

  5. 2 Interrupting Appropriately

    1 Interrupting someone politely e.g. Excuse me for interrupting, but may I ask a question? Sure. Of ...

  6. [转帖]Docker的数据管理(volume/bind mount/tmpfs)

    Docker(十五)-Docker的数据管理(volume/bind mount/tmpfs) https://www.cnblogs.com/zhuochong/p/10069719.html do ...

  7. 版本控制--git+idea

  8. Redis的java客户端jedis

    导包:Jedis需要的jar包 >Commons-pool-1.6.jar >Jedis-2.1.0.jar 配置:linux防火墙设置,不会设置就关闭. 停止防火墙 systemctl ...

  9. SSH的使用

    1.如何设置SSH的超时时间 使用SSH客户端软件登录linux服务器后,执行 echo $TMOUT可以查看SSH链接超时时间: 使用vim /etc/profile可以编辑配置页面 修改TMOUT ...

  10. mysql group by 对多个字段进行分组

    在平时的开发任务中我们经常会用到MYSQL的GROUP BY分组, 用来获取数据表中以分组字段为依据的统计数据.比如有一个学生选课表,表结构如下: Table: Subject_Selection S ...