这个题最暴力的搞法就是这样的:

设 $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] 序列统计 解题报告的更多相关文章

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

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

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

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

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

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

  4. 【SDOI2015】序列统计 解题报告

    2119: [BZOJ3992][SDOI2015]序列统计 Description 小\(C\)有一个集合\(S\),里面的元素都是小于\(M\)的非负整数. 他用程序编写了一个数列生成器,可以生成 ...

  5. [SDOI 2015]序列统计

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

  6. BZOJ 4004 [JLOI 2015] 装备购买 解题报告

    哎这个题 WA 了无数遍...果然人太弱... 首先我们把这些装备按照花费从小到大排序,然后依次考虑是否能买这个装备. 至于这样为什么是对的,好像有一个叫拟阵的东西可以证明,然而我不会.TATQAQ ...

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

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

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

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

  9. 洛谷 P1110 [ZJOI2007]报表统计 解题报告

    P1110 [ZJOI2007]报表统计 题目描述 \(Q\)的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小\(Q\)希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细 ...

随机推荐

  1. 关于Git和SVN的对比

    1.git的提交是一个DAG有向无欢图.可以看到哥哥分支之间的合并关系.SVN的提交是一条直线. 2.git的提交版本号不是一个简单递增的数字,而是一个长达40位的十六进制数字(哈希值) 但是可以适用 ...

  2. Magento中直接使用SQL语句

    原理: magento是基于Zend Framework的,所以底层用的还是zend的zend db 在文件app/code/core/Mage/Catalog/model/Resource/Eav ...

  3. c# 远程监控(2) 摄像头调研及模拟

    经过N多调研,最终选择了OpenCV(Emgu CV) ** 至于DirectShow, OpenCV等等其他大家可以百度,在这里我就不再赘述 环境:vs2010 vs2012 vs2013均可 Op ...

  4. Android中Tomcat的简单配置和使用

    因为学Android已经有一段时间了,但是在学校,服务器方面是个短板啊,没有专门的服务器拿给我们学生练手,所以只有自己找办法了.当然,Tomcat就是不二的选择了. 在网上看了看资料,还是觉得自己记录 ...

  5. C# 打印文件

    这几天做的功能用到了打印这个功能,直接在网上找了点demo,在这里做个备份. 1.直接打印DataTable using System; using System.Collections.Generi ...

  6. iOS 各种控件默认高度

    1.状态栏 状态栏一般高度为20像素,在打手机或者显示消息时会放大到40像素高,注意,两倍高度的状态栏在好像只能在纵向的模式下使用.如下图   用户可以隐藏状态栏,也可以将状态栏设置为灰色,黑色或者半 ...

  7. ios - cordova(phoneGap)

    安装教程 下载 node.js. http://nodejs.org/ 下载后,直接安装就可以了. 安装 Cordova工具, $ sudo npm install -g cordova 创建APP: ...

  8. OpenJudge / Poj 2141 Message Decowding

    1.链接地址: http://poj.org/problem?id=2141 http://bailian.openjudge.cn/practice/2141/ 2.题目: Message Deco ...

  9. DataList和Repeater

    DataList和Repeater是两个十分有用的控件,在新闻列表和图片展示的地方经常用到.在这里简单的把他们介绍一下. 1.DataList: 前端页面: <asp:DataList ID=& ...

  10. Linux中的简单命令

    history:打印你输过的命令      1.用户在shell中输入的命令会自动保存到内存缓冲区      2.在退出shell的时候,内存中的数据会刷新到磁盘文件:~/.bash_history ...