http://www.lydsy.com/JudgeOnline/problem.php?id=3992

这道题好难啊。

第一眼谁都能看出来是个dp,设\(f(i,j)\)表示转移到第i位时前i位的乘积模m等于j的方案数。

转移很显然啊\(f(i,j)=\sum_{x,y\in[0,m)}[xy\mod m=j]f(i-1,x)*f(i-1,y)\)。

这个下标是乘积取模的转移根本无法优化啊。

但注意到题目最下方说m是一个质数。。。

把x=0特判掉,剩下\(x\in[1,m-1)\)时把x转化为m的原根的幂次。

设m的原根为\(g_m\)。

那么\(f(i,g_m^j)=\sum_{x,y\in[0,m-1)}[(x+y)\mod m=j]f(i-1,g_m^x)*f(i-1,g_m^y)\)。

这样通过原根在[0,m-1)上的不重不漏的一一映射,乘积取模变成加法取模,化成了一个循环卷积的形式。

(话说看模数也知道是NTT啊qwq)循环卷积直接用NTT做就可以了。

但要做N次循环卷积,\(N\leq 10^9\)。。。

在外面套层快速幂就可以了O(∩_∩)O~~

快速幂套循环卷积的正确性?先不循环卷积然后再压成循环卷积就很好证明啊。不过也可以把快速幂看成一个倍增,每次合并两个dp数组之类的,正确性都显然啊qwq

注意数组不要开小!用于NTT的数组要开到2的幂次qwq

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

(看了Menci大大的博客,“把原根的幂次看成多项式的幂次,dp数组记录在系数里”这个东西还叫生成函数?)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll; const int M = 8193;
const int g = 267198;
const int p = 1004535809; int nin; int ipow(int a, int b) {
int ret = 1, w = a;
while (b) {
if (b & 1) ret = 1ll * ret * w % p;
w = 1ll * w * w % p;
b >>= 1;
}
return ret;
} int da[M << 1], db[M << 1], dc[M << 1], rev[M << 1], nWN[15], WN[15], n, m, x, s, C; void DNT(int *a, int *A, int flag) {
int tmp = 1;
for (int i = 0; i < n; ++i) A[rev[i]] = a[i];
for (int len = 2; len <= n; len <<= 1, ++tmp) {
int mid = len >> 1, wn = flag == 1 ? WN[tmp] : nWN[tmp];
for (int i = 0; i < n; i += len) {
int w = 1;
for (int j = 0; j < mid; ++j) {
int t = A[i + j], u = 1ll * A[i + j + mid] * w % p;
A[i + j] = (t + u) % p;
A[i + j + mid] = (t - u + p) % p;
w = 1ll * w * wn % p;
}
}
} if (flag == -1)
for (int i = 0; i < n; ++i)
A[i] = 1ll * A[i] * nin % p;
} int top; void NTTsqr(int *a) {
DNT(a, da, 1);
for (int i = 0; i < n; ++i)
da[i] = 1ll * da[i] * da[i] % p;
DNT(da, a, -1);
for (int i = 0; i < top; ++i) {
(a[i] += a[i + top]) %= p;
a[i + top] = 0;
}
} void NTT(int *a, int *b) {
DNT(a, da, 1); DNT(b, db, 1);
for (int i = 0; i < n; ++i)
dc[i] = 1ll * da[i] * db[i] % p;
DNT(dc, a, -1);
for (int i = 0; i < top; ++i) {
(a[i] += a[i + top]) %= p;
a[i + top] = 0;
}
} void init() {
int tot = 0, num = top << 1;
while (num) {num >>= 1; ++tot;}
n = 1 << tot;
nin = ipow(n, p - 2); int res;
for (int i = 0; i < n; ++i) {
num = i; res = 0;
for (int j = 0; j < tot; ++j) {
res <<= 1;
if (num & 1) res |= 1;
num >>= 1;
}
rev[i] = res;
} WN[14] = g, nWN[14] = ipow(g , p - 2);
for (int i = 13; i >= 1; --i) {
WN[i] = 1ll * WN[i + 1] * WN[i + 1] % p;
nWN[i] = 1ll * nWN[i + 1] * nWN[i + 1] % p;
}
} bool shown[M];
int r[M << 1], ww[M << 1], c[M]; int main() {
scanf("%d%d%d%d", &C, &m, &x, &s); top = m - 1;
if (x == 0) {printf("%d\n", (ipow(m, n) - ipow(m - 1, n) + p) % p); return 0;}
int num;
for (int i = 2; i < m; ++i) {
int ret = 1; bool flag = true;
for (int j = 0; j < top; ++j) {
ret = 1ll * ret * i % m;
if (shown[ret]) {flag = false; break;}
shown[ret] = true;
} if (!flag || ret != 1) {
ret = 1;
for (int j = 0; j < top; ++j) {
ret = 1ll * ret * i % m;
if (shown[ret]) shown[ret] = false;
else break;
}
} else {
num = i;
break;
}
} int ret = 1;
for (int i = 0; i < top; ++i) {
c[ret] = i;
ret = 1ll * ret * num % m;
} init(); int tt;
for (int i = 1; i <= s; ++i) {
scanf("%d", &tt);
if (tt != 0) ww[c[tt]] = 1;
} r[0] = 1;
while (C) {
if (C & 1) NTT(r, ww);
NTTsqr(ww);
C >>= 1;
} printf("%d\n", r[c[x]]); return 0;
}

【BZOJ 3993】【SDOI 2015】序列统计的更多相关文章

  1. [BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT)

    [BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT) 题面 小C有一个集合S,里面的元素都是小于质数M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数 ...

  2. BZOJ 3992 [SDOI 2015] 序列统计 解题报告

    这个题最暴力的搞法就是这样的: 设 $Dp[i][j]$ 为前 $i$ 个数乘积为 $j$ 的方案数. 转移的话就不多说了哈... 当前复杂度 $O(nm^2)$ 注意到,$M$ 是个质数,就说明 $ ...

  3. [BZOJ 3992] [SDOI 2015] 序列统计

    Description 传送门 Solution [一] 设 \(f[i][j]\) 表示前 \(i\) 个数的乘积在模 \(p\) 意义下等于 \(j\) 的方案数,有 \[ f[i][j]=\su ...

  4. BZOJ 3993 [SDOI 2015] 星际战争 解题报告

    首先我们可以二分答案. 假设当前二分出来的答案是 $Ans$ ,那么我们考虑用网络流检验: 设武器为 $X$,第 $i$ 个武器的攻击力为 $B_i$: 设机器人为 $Y$,第 $i$ 个机器人的装甲 ...

  5. [SDOI 2015]序列统计

    Description 题库链接 给出集合 \(S\) ,元素都是小于 \(M\) 的非负整数.问能够生成出多少个长度为 \(N\) 的数列 \(A\) ,数列中的每个数都属于集合 \(S\) ,并且 ...

  6. 【BZOJ 4403】 4403: 序列统计 (卢卡斯定理)

    4403: 序列统计 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 653  Solved: 320 Description 给定三个正整数N.L和R, ...

  7. [BZOJ 4818] [SDOI 2017] 序列计数

    Description Alice想要得到一个长度为 \(n\) 的序列,序列中的数都是不超过 \(m\) 的正整数,而且这 \(n\) 个数的和是 \(p\) 的倍数. Alice还希望,这 \(n ...

  8. 【BZOJ】3992: [SDOI2015]序列统计 NTT+生成函数

    [题意]给定一个[0,m-1]范围内的数字集合S,从中选择n个数字(可重复)构成序列.给定x,求序列所有数字乘积%m后为x的序列方案数%1004535809.1<=n<=10^9,3< ...

  9. BZOJ 3990 [SDOI 2015] 排序 解题报告

    这个题哎呀...细节超级多... 首先,我猜了一个结论.如果有一种排序方案是可行的,假设这个方案是 $S$ . 那么我们把 $S$ 给任意重新排列之后,也必然可以构造出一组合法方案来. 于是我们就可以 ...

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

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

随机推荐

  1. CCD和CMOS的差别

    单从感光器电子技术上来说,CCD比CMOS更先进,理论成像上有优势,但是最近几年CMOS却发展更好,使得很多高端数码单反采用CMOS传感器,下面来看看CCD和CMOS的技术知识: CCD和CMOS传感 ...

  2. hdu5909 Tree Cutting

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5909 [题解] 设$f_{x,i}$表示以$x$节点的子树中,权值为$i$的子树个数,其中$x$必选. ...

  3. C++正则表达式例子

    给了策划配置公式的地方,需要将策划配置的公式文本转化为可执行的脚本代码:比如:self->mHp*2+target->2mMp*GetHit()+ self_mon->4mDan/1 ...

  4. .net XmlHelper xml帮助类

    using System.Data; using System.IO; using System.Xml; using System.Xml.Serialization; /// <summar ...

  5. Keil MDK 5.14 仿真时System Viewer菜单显示空白和Peripherals菜单无外设寄存器

    keil mdk5.14新建工程进行仿真时,进入Debug环境发现System Viewer菜单显示空白,Peripherals菜单没有外设寄存器.如图1和图2所示.打开Oprons for Targ ...

  6. linux dpm机制分析(上)【转】

    转自:http://blog.csdn.net/lixiaojie1012/article/details/23707681 1      DPM介绍 1.1        Dpm:  设备电源管理, ...

  7. [New learn]AutoLayout调查基于code

    代码https://github.com/xufeng79x/TestAutolayout-code2 0.插在前面 必须关闭view的自动缩放掩码,自动缩放掩码是autolayout出现之前系统管理 ...

  8. HIbernate学习笔记4 之 延迟加载和 关联映射

    一.延迟加载 * 在使用hibernate一些方法的查询数据的时候,返回的只是一个空对象(除id外属性都为NULL),并没有真正的查询数据库,而是在使用这个对象时才会触发查询数据库,并将这些数据注入到 ...

  9. 关于springMVC转换json出现的异常

    jackson-core-asl-1.9.0.jar,jackson-mapper-asl-1.9.0.jar两个包 并且在controller中有如下代码 @RequestMapping(value ...

  10. LeetCode218. The Skyline Problem

    https://leetcode.com/problems/the-skyline-problem/description/ A city's skyline is the outer contour ...