BZOJ 3992 [SDOI 2015] 序列统计 解题报告
2015-04-16 09:11
337 查看
这个题最暴力的搞法就是这样的:
设 $Dp[i][j]$ 为前 $i$ 个数乘积为 $j$ 的方案数。
转移的话就不多说了哈。。。
当前复杂度 $O(nm^2)$
注意到,$M$ 是个质数,就说明 $M$ 有原根并且我们可以很快的求出来。
于是对于 $1\rightarrow M-1$ 中的每一个数都可以表示成原根的某次幂。
于是乘法可以转化为原根的幂的加法,
转移的时候就相当于做多项式乘法了。
我们再注意到,$1004535809 = 479 \times 2^{21} + 1$ 并且是个质数,原根为 $3$。
于是转移的时候就可以用 $FFT$ 优化了。
当前复杂度 $O(nm\log m)$
我们再考虑,每次多项式乘法中乘的多项式都是一样的,那么是不是就可以快速幂啊?
当前复杂度 $O(m\log m\log n)$,可以 A 掉这个题啦~
注意那些等于 $0$ 的数。。。
具体细节自己脑补脑补吧~
3992_Gromah
设 $Dp[i][j]$ 为前 $i$ 个数乘积为 $j$ 的方案数。
转移的话就不多说了哈。。。
当前复杂度 $O(nm^2)$
注意到,$M$ 是个质数,就说明 $M$ 有原根并且我们可以很快的求出来。
于是对于 $1\rightarrow M-1$ 中的每一个数都可以表示成原根的某次幂。
于是乘法可以转化为原根的幂的加法,
转移的时候就相当于做多项式乘法了。
我们再注意到,$1004535809 = 479 \times 2^{21} + 1$ 并且是个质数,原根为 $3$。
于是转移的时候就可以用 $FFT$ 优化了。
当前复杂度 $O(nm\log m)$
我们再考虑,每次多项式乘法中乘的多项式都是一样的,那么是不是就可以快速幂啊?
当前复杂度 $O(m\log m\log n)$,可以 A 掉这个题啦~
注意那些等于 $0$ 的数。。。
具体细节自己脑补脑补吧~
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; #define N 16384 + 5 #define Mod 1004535809 #define g 3 int n, p, x, m, len, w, d, root, inv_len, ans; int T , Num , Pos ; int A , B , C , Rev , e[2] ; inline int power(int u, int v, int p) { int res = 1; for (; v; v >>= 1) { if (v & 1) res = (LL) res * u % p; u = (LL) u * u % p; } return res; } inline void Init() { scanf("%d%d%d%d", &n, &p, &x, &m); for (int i = 1; i <= m; i ++) scanf("%d", T + i); for (len = p << 1; len != (len & -len); len += (len & -len)) ; for (int i = len; i > 1; i >>= 1) d ++; inv_len = power(len, Mod - 2, Mod); w = power(g, (Mod - 1) / len, Mod); } inline bool Judge(int x, int p) { for (int i = 2; i * i <= p; i ++) if ((p - 1) % i == 0 && power(x, (p - 1) / i, p) == 1) return 0; return 1; } inline int Find_Root(int p) { if (p == 2) return 1; int res = 2; for (; !Judge(res, p); res ++) ; return res; } inline void Prepare() { root = Find_Root(p); for (int i = 0; i < p - 1; i ++) { Num[i] = !i ? 1 : Num[i - 1] * root % p; Pos[Num[i]] = i; } } inline int Inc(int u, int v) { return u + v - (u + v >= Mod ? Mod : 0); } inline void FFT(int *Ar, int op) { for (int i = 0; i < len; i ++) if (Rev[i] > i) swap(Ar[i], Ar[Rev[i]]); for (int k = 1, s = 1; k < len; k <<= 1, s ++) for (int i = 0; i < len; i ++) { if (i & k) continue ; int t = (i & k - 1) << d - s; int u = Inc(Ar[i], (LL) Ar[i + k] * e[op][t] % Mod); int v = Inc(Ar[i], Mod - ((LL) Ar[i + k] * e[op][t] % Mod)); Ar[i] = u, Ar[i + k] = v; } } inline void Convol(int *U, int *V) { for (int i = 0; i < len; i ++) C[i] = V[i]; FFT(U, 0), FFT(C, 0); for (int i = 0; i < len; i ++) U[i] = (LL) U[i] * C[i] % Mod; FFT(U, 1); for (int i = 0; i < len; i ++) U[i] = (LL) U[i] * inv_len % Mod; for (int i = len - 1; i >= p - 1; i --) { U[i - p + 1] = Inc(U[i - p + 1], U[i]); U[i] = 0; } } inline void Solve() { A[0] = 1; for (int i = 1; i <= m; i ++) { if (T[i] == 0) continue ; B[Pos[T[i]]] ++; } for (int i = 0, inv_w = power(w, Mod - 2, Mod); i < len; i ++) { e[0][i] = !i ? 1 : (LL) e[0][i - 1] * w % Mod; e[1][i] = !i ? 1 : (LL) e[1][i - 1] * inv_w % Mod; for (int j = 0; j < d; j ++) if ((i >> j) & 1) Rev[i] += 1 << (d - j - 1); } for (; n; n >>= 1) { if (n & 1) Convol(A, B); Convol(B, B); } ans = A[Pos[x]]; } int main() { #ifndef ONLINE_JUDGE freopen("sequence.in", "r", stdin); freopen("sequence.out", "w", stdout); #endif Init(); Prepare(); Solve(); printf("%d\n", ans); #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); #endif return 0; }
3992_Gromah
相关文章推荐
- [NTT 原根 指标 多项式快速幂] BZOJ 3992 [SDOI2015]序列统计
- BZOJ3992:[SDOI2015]序列统计
- bzoj3992 [SDOI2015]序列统计
- 【动态规划】bzoj3992 [Sdoi2015]序列统计 10分
- [BZOJ3992][SDOI2015]序列统计(dp+NTT+快速幂)
- BZOJ3992 : [SDOI2015]序列统计
- bzoj 3992: [SDOI2015]序列统计 NTT
- BZOJ3992 SDOI2015 序列统计
- bzoj3992: [SDOI2015]序列统计 快速数论变换NTT+矩阵优化
- BZOJ 3992 [SDOI2015]序列统计 NTT
- BZOJ3992 [SDOI2015]序列统计 【生成函数 + 多项式快速幂】
- bzoj3992 [SDOI2015]序列统计(从一道题入手NTT)
- BZOJ3992 [SDOI2015]序列统计
- BZOJ 3992: [SDOI2015]序列统计(NTT+快速幂+DP)
- bzoj 3992: [SDOI2015]序列统计 (NTT+快速幂+DP)
- 【 bzoj 3992 】 [SDOI2015]序列统计 - NTT 生成函数
- BZOJ 3992: [SDOI2015]序列统计 NTT+快速幂
- BZOJ3992:[SDOI2015]序列统计——题解
- BZOJ 3992: [SDOI2015]序列统计
- BZOJ 3992: [SDOI2015]序列统计