BZOJ 3992 [SDOI 2015] 序列统计 解题报告
这个题最暴力的搞法就是这样的:
设 $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[N], Num[N], Pos[N];
int A[N], B[N], C[N], Rev[N], e[][N]; inline int power(int u, int v, int p)
{
int res = ;
for (; v; v >>= )
{
if (v & ) 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 = ; i <= m; i ++)
scanf("%d", T + i);
for (len = p << ; len != (len & -len); len += (len & -len)) ;
for (int i = len; i > ; i >>= ) d ++;
inv_len = power(len, Mod - , Mod);
w = power(g, (Mod - ) / len, Mod);
} inline bool Judge(int x, int p)
{
for (int i = ; i * i <= p; i ++)
if ((p - ) % i == && power(x, (p - ) / i, p) == ) return ;
return ;
} inline int Find_Root(int p)
{
if (p == ) return ;
int res = ;
for (; !Judge(res, p); res ++) ;
return res;
} inline void Prepare()
{
root = Find_Root(p);
for (int i = ; i < p - ; i ++)
{
Num[i] = !i ? : Num[i - ] * root % p;
Pos[Num[i]] = i;
}
} inline int Inc(int u, int v)
{
return u + v - (u + v >= Mod ? Mod : );
} inline void FFT(int *Ar, int op)
{
for (int i = ; i < len; i ++)
if (Rev[i] > i) swap(Ar[i], Ar[Rev[i]]);
for (int k = , s = ; k < len; k <<= , s ++)
for (int i = ; i < len; i ++)
{
if (i & k) continue ;
int t = (i & k - ) << 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 = ; i < len; i ++)
C[i] = V[i];
FFT(U, ), FFT(C, );
for (int i = ; i < len; i ++)
U[i] = (LL) U[i] * C[i] % Mod;
FFT(U, );
for (int i = ; i < len; i ++)
U[i] = (LL) U[i] * inv_len % Mod;
for (int i = len - ; i >= p - ; i --)
{
U[i - p + ] = Inc(U[i - p + ], U[i]);
U[i] = ;
}
} inline void Solve()
{
A[] = ;
for (int i = ; i <= m; i ++)
{
if (T[i] == ) continue ;
B[Pos[T[i]]] ++;
}
for (int i = , inv_w = power(w, Mod - , Mod); i < len; i ++)
{
e[][i] = !i ? : (LL) e[][i - ] * w % Mod;
e[][i] = !i ? : (LL) e[][i - ] * inv_w % Mod;
for (int j = ; j < d; j ++)
if ((i >> j) & ) Rev[i] += << (d - j - );
}
for (; n; n >>= )
{
if (n & ) 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 ;
}
3992_Gromah
BZOJ 3992 [SDOI 2015] 序列统计 解题报告的更多相关文章
- [BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT)
[BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT) 题面 小C有一个集合S,里面的元素都是小于质数M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数 ...
- [BZOJ 3992] [SDOI 2015] 序列统计
Description 传送门 Solution [一] 设 \(f[i][j]\) 表示前 \(i\) 个数的乘积在模 \(p\) 意义下等于 \(j\) 的方案数,有 \[ f[i][j]=\su ...
- BZOJ 3993 [SDOI 2015] 星际战争 解题报告
首先我们可以二分答案. 假设当前二分出来的答案是 $Ans$ ,那么我们考虑用网络流检验: 设武器为 $X$,第 $i$ 个武器的攻击力为 $B_i$: 设机器人为 $Y$,第 $i$ 个机器人的装甲 ...
- 【SDOI2015】序列统计 解题报告
2119: [BZOJ3992][SDOI2015]序列统计 Description 小\(C\)有一个集合\(S\),里面的元素都是小于\(M\)的非负整数. 他用程序编写了一个数列生成器,可以生成 ...
- [SDOI 2015]序列统计
Description 题库链接 给出集合 \(S\) ,元素都是小于 \(M\) 的非负整数.问能够生成出多少个长度为 \(N\) 的数列 \(A\) ,数列中的每个数都属于集合 \(S\) ,并且 ...
- BZOJ 4004 [JLOI 2015] 装备购买 解题报告
哎这个题 WA 了无数遍...果然人太弱... 首先我们把这些装备按照花费从小到大排序,然后依次考虑是否能买这个装备. 至于这样为什么是对的,好像有一个叫拟阵的东西可以证明,然而我不会.TATQAQ ...
- 【BZOJ 4403】 4403: 序列统计 (卢卡斯定理)
4403: 序列统计 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 653 Solved: 320 Description 给定三个正整数N.L和R, ...
- BZOJ 3990 [SDOI 2015] 排序 解题报告
这个题哎呀...细节超级多... 首先,我猜了一个结论.如果有一种排序方案是可行的,假设这个方案是 $S$ . 那么我们把 $S$ 给任意重新排列之后,也必然可以构造出一组合法方案来. 于是我们就可以 ...
- 洛谷 P1110 [ZJOI2007]报表统计 解题报告
P1110 [ZJOI2007]报表统计 题目描述 \(Q\)的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小\(Q\)希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细 ...
随机推荐
- 哇!今天找到一个非常好用的自动补全插件-necomplete.vim
看别人说的什么xpcomplete,snipte,拿来都不会用,这个necomplete.vim还挺好用的,不用去按C-X,C-O进行补全,把关键字自动的列出来,调用的是用户自定义补全,^u^n^p的 ...
- 使用jstack分析java程序cpu占用率过高
在项目中经常会碰到CPU占用率过高的问题,那么碰到这类问题应当如何处理呢?下面提供一种处理思路: 首先top -H -p <pid>以线程的模式查看java应用的运行情况,找到占用cpu或 ...
- windows7 图形界面远程 centos6.5
一.首先确定centos已经安装了gnome,因为centos自身没有图形界面,别说远程图形界面方式访问了,就本地图像界面方式都不行 1.首先查看系统的运行级别以及是否安装了桌面环境 1.使用命 ...
- PHP生成HTML页面顶部出现空白部分(字符?)
参考了:PHP生成HTML页面顶部出现空白部分(#65279字符?)的解决办法 查看拼接两个Html,查看文件格式是否是UTF-8 无Bom,我的内容Html是UTF-8 + Bom.
- 【转】SharePoint工作流中常用的方法
SharePoint中使用工作流对象模型. SharePoint工作流对象模型在Microsoft.SharePoint.Workflow命名空间.你可以利用此对象模型对你的工作流进行编程.你可以启动 ...
- 初步接触html心得
接触HTML大概有七天,做一下小总结,过过记忆. html大致可分为三部分:Dtd头.Head.Body三大部分. Dtd头:是用于浏览器编辑的,也就是俗话说的给电脑看的的东西. Head:内细分下大 ...
- C++多态性与C#的比较
多态性:统一操作作用于不同的对象可以有不同的解释,产生不同的执行结果.多态性可以分为两种:一是编译时的多态性,一是运行时的多态性. 编译时的多态性包括重载.覆盖.运算符重载.对于非虚的 ...
- 阻止子View获取焦点方法
android:descendantFocusability:ViewGroup ep: android:descendantFocusability=blocksDescendants
- 关于css中的align-content属性详解
align-content 作用: 会设置自由盒内部各个项目在垂直方向排列方式. 条件:必须对父元素设置自由盒属性display:flex;,并且设置排列方式为横向排列flex-direction:r ...
- JSP九大内置对象(转载)
JSP中一共预先定义了9个这样的对象,分别为:request.response.session.application.out.pagecontext.config.page.exception 1. ...