题目描述

求长度为 $n$ 的序列,每个数都是 $|S|$ 中的某一个,所有数的乘积模 $m$ 等于 $x$ 的序列数目模1004535809的值。

输入

一行,四个整数,N、M、x、|S|,其中|S|为集合S中元素个数。
第二行,|S|个整数,表示集合S中的所有元素。
1<=N<=10^9,3<=M<=8000,M为质数
1<=x<=M-1,输入数据保证集合S中元素不重复

输出

一行,一个整数,表示你求出的种类数mod 1004535809的值。

样例输入

4 3 1 2
1 2

样例输出

8


题解

原根+NTT

如果条件是和模 $m$ 等于 $x$ ,那么很明显就是一道NTT裸题。维护S集合的生成函数在模 $x^m$ 意义下的 $n$ 次幂即可。

然而本题的条件是乘积。可以求出 $m$ 的原根,对每个数取指标,那么原数相乘就变为指标相加,使用NTT快速幂即可。

求原根的过程可以直接暴力。

注意 $|S|$ 集合中的数可能有0,0是没有指标的。由于 $x\neq 0$ ,因此出现0时无意义,直接忽略这个数即可。

时间复杂度 $O(m\log^2n)$

#include <cstdio>
#include <algorithm>
#define N 16410
#define mod 1004535809
using namespace std;
typedef long long ll;
int m , s[N >> 1] , v[15] , tot , ind[N >> 1];
ll a[N] , ans[N];
inline ll pow(ll x , int y , ll m)
{
ll ans = 1;
while(y)
{
if(y & 1) ans = ans * x % m;
x = x * x % m , y >>= 1;
}
return ans;
}
int getroot()
{
int i , j , t = m - 1;
for(i = 2 ; i * i <= t ; i ++ )
{
if(t % i == 0)
{
v[++tot] = i;
while(t % i == 0) t /= i;
}
}
if(t != 1) v[++tot] = t;
for(i = 2 ; i < m ; i ++ )
{
for(j = 1 ; j <= tot ; j ++ )
if(pow(i , (m - 1) / v[j] , m) == 1)
break;
if(j > tot) return i;
}
return 0;
}
void ntt(ll *a , int n , int flag)
{
int i , j , k;
for(k = i = 0 ; i < n ; i ++ )
{
if(i > k) swap(a[i] , a[k]);
for(j = (n >> 1) ; (k ^= j) < j ; j >>= 1);
}
for(k = 2 ; k <= n ; k <<= 1)
{
ll wn = pow(3 , (mod - 1) / k , mod);
if(flag == -1) wn = pow(wn , mod - 2 , mod);
for(i = 0 ; i < n ; i += k)
{
ll w = 1 , t;
for(j = i ; j < i + (k >> 1) ; j ++ , w = w * wn % mod)
t = w * a[j + (k >> 1)] % mod , a[j + (k >> 1)] = (a[j] - t + mod) % mod , a[j] = (a[j] + t) % mod;
}
}
if(flag == -1)
{
k = pow(n , mod - 2 , mod);
for(i = 0 ; i < n ; i ++ ) a[i] = a[i] * k % mod;
for(i = m - 1 ; i < n ; i ++ ) a[i % (m - 1)] = (a[i % (m - 1)] + a[i]) % mod , a[i] = 0;
}
}
void Pow(int y , int n)
{
int i;
ans[0] = 1;
while(y)
{
ntt(a , n , 1);
if(y & 1)
{
ntt(ans , n , 1);
for(i = 0 ; i < n ; i ++ ) ans[i] = ans[i] * a[i] % mod;
ntt(ans , n , -1);
}
for(i = 0 ; i < n ; i ++ ) a[i] = a[i] * a[i] % mod;
ntt(a , n , -1);
y >>= 1;
}
}
int main()
{
int n , x , k , i , r , t , len = 1;
scanf("%d%d%d%d" , &n , &m , &x , &k);
for(i = 1 ; i <= k ; i ++ ) scanf("%d" , &s[i]);
r = getroot();
for(t = 1 , i = 0 ; i < m - 1 ; i ++ , t = t * r % m) ind[t] = i;
for(i = 1 ; i <= k ; i ++ )
if(s[i])
a[ind[s[i]]] ++ ;
while(len <= 2 * (m - 2)) len <<= 1;
Pow(n , len);
printf("%lld\n" , ans[ind[x]]);
return 0;
}

【bzoj3992】[SDOI2015]序列统计 原根+NTT的更多相关文章

  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】序列统计 原根 NTT

    题目大意 有一个集合\(s\),里面的每个数都\(\geq0\)且\(<m\). 问有多少个长度为\(n\)的数列满足这个数列所有数的乘积模\(m\)为\(x\).答案模\(1004535809 ...

  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. 20155336 《Java程序设计》实验二 (Java面向对象程序设计)实验报告

    20155336 <Java程序设计>实验二 (Java面向对象程序设计)实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉 ...

  2. NetWork——TCP的流量控制和拥塞控制

    ,然后开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大. 这里为什么替换掉了慢开始算法呢,这是因为收到重复的ACK不仅仅告诉我们一个分组丢失了,由于接收方只有在收到另一个报文段时才会产生重复的ACK,所 ...

  3. 1109: [POI2007]堆积木Klo

    1109: [POI2007]堆积木Klo https://lydsy.com/JudgeOnline/problem.php?id=1109 分析: 首先是dp,f[i]表示到第i个的最优值,f[i ...

  4. spark submit参数及调优(转载)

    spark submit参数介绍 你可以通过spark-submit --help或者spark-shell --help来查看这些参数. 使用格式:  ./bin/spark-submit \ -- ...

  5. angularJS ng-repeat中的directive 动态加载template

    有个需求,想实现一个html组件,传入不同的typeId,渲染出不同的表单元素. <div ng-repeat="field in vm.data"> <magi ...

  6. NLP的12条精髓

    NLP是神经语言程序学 (Neuro-Linguistic Programming) 的英文缩写.一.没有两个人是一样的 No two persons are the same. 1.没有两个人的人生 ...

  7. appium+python自动化☞环境搭建

    前言:appium可以说是做app最火的一个自动化框架,它的主要优势是支持android和ios,另外脚本语言也是支持java和Python.略懂Python,所以接下来的教程是 appium+pyt ...

  8. html js div随鼠标移动

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. 网络流小结(HNOI2019之前)

    \(\text{一:Dinic最大流}\) 最坏复杂度 \({\mathcal O(n^2m)}\) 一般可以处理 \(10^4\) ~ \(10^5\) 的网络. struct Edge { int ...

  10. 冲刺ing-5

    第五次Scrum冲刺 队员完成的任务 队员 完成任务 吴伟华 Leangoo的看板截图,燃尽图 蔺皓雯 编写博客 蔡晨旸 测试 曾茜 测试 鲁婧楠 测试 杨池宇 测试 成员遇到的问题 队员 问题 吴伟 ...