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\)希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细 ...
随机推荐
- centos vim 中文乱码解决方案
1.安装中文包:yum -y groupinstall chinese-support 2.修改字符编码配置文件 vi /etc/sysconfig/i18n LANGUAGE="zh_ ...
- 在Activiti官方源码上提交的两个bugfix
前段时间在Activiti官方源码上提交了两个bugfix,截图为证. 第1个是BPMN model输出的bug:
- 支持BLOB操作的Jena框架扩展——JenaBLOB
与研究语义网的同行们分享一下上半年做的一个东西,它是支持BLOB操作的Jena框架扩展--JenaBLOB,已在GitHub上开源,欢迎提出宝贵意见! 众所周知,Jena是不支持BLOB类型的Lite ...
- Oracle12c创建新用户提示公共用户名或角色无效
今天将备份的数据库还原到一台新的电脑上,首先要创建用户,执行如下语句: create user fxhy identified " default tablespace USERS temp ...
- ASP中双引号单引号和&连接符使用技巧
ASP中双引号单引号和&连接符使用技巧 一.ASP中处在双引号中的可以是任意的字符.字符串,HTML代码 1.<%response.write ("I am here" ...
- Microsoft JScript 运行时错误: Sys.WebForms.PageRequestManagerParserErrorException无法分析从服务器收到的消息。之所以出现此错误,
Microsoft JScript 运行时错误: Sys.WebForms.PageRequestManagerParserErrorException: 无法分析从服务器收到的消息.之所以出现此错误 ...
- python学习第二天:数字与字符串转换及逻辑值
1.数字与字符串的转化 #1.数字转字符,使用格式化字符串: *1.demo = ‘%d’ % source *2.%d整型:%f 浮点型 :%e科学计数 ...
- vmware workstation 12 安装windows7 网卡不能安装驱动的问题
在使用vmware workstation 12 安装windows7 之后,网卡不能安装驱动不能正常显示网络连接,需要修改该虚拟机的".vmx"配置文件 在配置文件中添加下面一行 ...
- Java_Web学习路线
- 在linux CentOS6上安装web环境
感谢浏览,欢迎交流=.= 都说linux作为服务器优于window,近期也是学习了下linux. win7下安装了linux虚拟机,购买linux阿里云主机,开启linux之旅. 进入正题,在linu ...