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

设 $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. Visual Studio dte 获取代码方法注释

  2. ArrayList、Vector、LinkedList的区别及其优缺点? (转载)

    原文链接:http://blog.csdn.net/wangzff/article/details/7296648 ArrayList,LinkedList,Vestor这三个类都实现了java.ut ...

  3. items 与iteritems

    dict的items函数返回的是键值对的元组的列表,而iteritems使用的是键值对的generator. items当使用时会调用整个列表 iteritems当使用时只会调用值. >> ...

  4. javascript RegExp类型 学习小记

    在js里面,可以有两种方法来定义正则表达式,第一种是通过字变量的形式,第二种则是通过构造函数的形式: 1 字变量形式,格式是长这样子的 var expression = /pattern/flag p ...

  5. 07_控制线程_join_线程插队

    [join线程简述] join()方法:Thread提供的让一个线程去等待另一个线程完成.当在某个程序执行流中(如main线程)调用其它线程(如t2线程)的join方法(t2.join()),调用线程 ...

  6. css中>,+,~的用法

    1.>的用法 A>B选择A的所有子元素B(只选择一代) 2.+的用法 A+B选择紧随着A的兄弟元素B 3.~的用法 A~B选择位置处于A后面的所有兄弟元素B(不包含兄弟元素的子元素)

  7. centos 端口开放及关闭

    之前有讲过公司新买的服务器使用的是CentOS 5.5,部署好Tomcat之后却发现输入114.80.*.*:8080(即ip:8080)却无法显示Tomcat默认的首页.因为以前部署在Win Ser ...

  8. (转载)使用ADOConnet.BeginTrans后,出现错误提示:无法在此会话中启动更多的事务?

    Q: 三层结构,在服务器端使用adoconnection连接到sqlserver2000,然后想在 datasetprovider的beforupdaterecord中使用语句: try adocon ...

  9. 《C和指针》读书笔记——第二章 基本概念

    1.编译过程: source code→Compiler→Object code→Linker←Lib ↓ Exe 2.经过初始化的静态变量(static)在程序执行前能获得他们的值. 3.绝大多数环 ...

  10. [Python][flask][flask-login]关于flask-login中各种API使用实例

    本篇博文跟上一篇[Python][flask][flask-wtf]关于flask-wtf中API使用实例教程有莫大的关系. 简介:Flask-Login 为 Flask 提供了用户会话管理.它处理了 ...