Description

Alice想要得到一个长度为 \(n\) 的序列,序列中的数都是不超过 \(m\) 的正整数,而且这 \(n\) 个数的和是 \(p\) 的倍数。

Alice还希望,这 \(n\) 个数中,至少有一个数是质数。

Alice想知道,有多少个序列满足她的要求。

Input

一行三个数,\(n,m,p\)。

Output

一行一个数,满足Alice的要求的序列数量,答案对 \(20170408\) 取模。

Sample Input

3 5 3

Sample Output

33

HINT

对 \(20\%\) 的数据,\(1\leq n,m\leq100\)

对 \(50\%\) 的数据,\(1\leq m \leq 100\)

对 \(80\%\) 的数据,\(1\leq m\leq 10^6\)

对 \(100\%\) 的数据,\(1\leq n \leq 10^9,1\leq m \leq 2\times 10^7,1\leq p\leq 100\)

Solution

设 \(f[i][j]\) 表示前 \(i\) 位之和模 \(p\) 等于 \(j\) 的方案数,\(g[i]\) 表示在模 \(p\) 意义下等于 \(i\) 的数的个数,有

\[f[i][j]=f[i-1][k]\cdot g[(j+p-k)\bmod p],0\le k < p
\]

可构造出转移矩阵

\[\begin{bmatrix}
g_0&g_{p-1}&\cdots&g_{1}\\
g_{1}&g_{0}&\cdots&g_{2}\\
\vdots&\vdots&\ddots&\vdots\\
g_{p-1}&g_{p-2}&\cdots&g_{0}
\end{bmatrix}
\begin{bmatrix}
f_0\\
f_1\\
\vdots\\
f_{p-1}
\end{bmatrix}
\]

最后用总的答案减去不包含质数的答案。

再科普一下NTT做法:

\[(g_0+g_1x+g_2x^2+\cdots+g_{p-1}x^{p-1})^{n-1}
\]

Code

#include <cstdio>
#include <cstring> const int N = 20000002, mod = 20170408;
int n, m, p, pr[N], np[N], tot, f[102], g[102]; struct Matrix {
int mat[102][102];
Matrix(){ memset(mat, 0, sizeof mat); }
Matrix operator * (const Matrix a) const {
Matrix b;
for (int i = 1; i <= p; ++i)
for (int j = 1; j <= p; ++j)
for (int k = 1; k <= p; ++k)
b.mat[i][j] = (b.mat[i][j] + 1LL * a.mat[i][k] * mat[k][j]) % mod;
return b;
}
} unit, a, b;
void sieve() {
np[1] = 1;
for (int i = 2; i <= m; ++i) {
if (!np[i]) pr[++tot] = i;
for (int j = 1; j <= tot && i * pr[j] <= m; ++j) {
np[i * pr[j]] = 1;
if (i % pr[j] == 0) break;
}
}
}
int ksm(Matrix a, int b) {
Matrix res = unit;
for (; b; b >>= 1, a = a * a)
if (b & 1) res = res * a;
return res.mat[1][1];
}
int main() {
scanf("%d%d%d", &n, &m, &p);
sieve();
for (int i = 1; i <= p; ++i) unit.mat[i][i] = 1;
for (int i = 1; i <= m; ++i) ++f[i % p];
for (int i = 1; i <= m; ++i) if (np[i]) ++g[i % p];
for (int i = 1; i <= p; ++i) {
int k = 1;
for (int j = i - 1; j >= 0; --j, ++k) a.mat[i][k] = f[j], b.mat[i][k] = g[j];
for (int j = p - 1; j >= i; --j, ++k) a.mat[i][k] = f[j], b.mat[i][k] = g[j];
}
printf("%d\n", (ksm(a, n) - ksm(b, n) + mod) % mod);
return 0;
}

[BZOJ 4818] [SDOI 2017] 序列计数的更多相关文章

  1. [BZOJ 4818/LuoguP3702][SDOI2017] 序列计数 (矩阵加速DP)

    题面: 传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4818 Solution 看到这道题,我们不妨先考虑一下20分怎么搞 想到暴力,本蒟 ...

  2. [SDOI 2017] 序列计数

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=4818 [算法] 考虑容斥 , 用有至少有一个质数的合法序列数 - 没有质数的合法序列 ...

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

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

  4. BZOJ 3992 [SDOI 2015] 序列统计 解题报告

    这个题最暴力的搞法就是这样的: 设 $Dp[i][j]$ 为前 $i$ 个数乘积为 $j$ 的方案数. 转移的话就不多说了哈... 当前复杂度 $O(nm^2)$ 注意到,$M$ 是个质数,就说明 $ ...

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

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

  6. [BZOJ 4817] [SDOI 2017] 树点涂色

    Description Bob有一棵 \(n\) 个点的有根树,其中 \(1\) 号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点(包括起点和终点 ...

  7. [BZOJ 4819] [SDOI 2017] 新生舞会

    Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴. 有 \(n\) 个男生和 \(n\) 个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴. C ...

  8. 【BZOJ 4818】 4818: [Sdoi2017]序列计数 (矩阵乘法、容斥计数)

    4818: [Sdoi2017]序列计数 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 560  Solved: 359 Description Al ...

  9. BZOJ4818 序列计数

    4818: [Sdoi2017]序列计数 Time Limit: 30 Sec  Memory Limit: 128 MB Description Alice想要得到一个长度为n的序列,序列中的数都是 ...

随机推荐

  1. [HTML/CSS]colum-gap属性

    属性定义及使用说明 column-gap的属性指定的列之间的差距. 注意: 如果指定了列之间的距离规则,它会取平均值.   语法 column-gap: length|normal;   值 描述 l ...

  2. Dynamics 365 CE中AsyncOperationBase表记录太多,影响系统性能怎么办?

    微软动态CRM专家罗勇 ,回复311或者20190311可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 本文主要是根据微软官 ...

  3. 自然语言处理(nlp)比计算机视觉(cv)发展缓慢,而且更难!

    https://mp.weixin.qq.com/s/kWw0xce4kdCx62AflY6AzQ 1.  抢跑的nlp nlp发展的历史非常早,因为人从计算机发明开始,就有对语言处理的需求.各种字符 ...

  4. Python模块time、datetime

    模块: 模块是一系列常用功能的集合体,一个py文件就是一个模块. 一.模块的作用: 1.从文件级别组织程序,方便管理,随着程序的发展,功能越来越多,我们通常将程序分成一个个py文件,这样做程序的结构更 ...

  5. Xshell连接linux主机

    一.获取linux主机的ip地址.用户名.密码 二.xshell里面建立连接 三.打开连接,操作远程linux主机

  6. Java中a+=b和a=a+b的区别

    在Java语言中a+=b和a=a+b是有区别的,主要的区别是在运算时精度的问题,当然了-=.*=./=,%=也都是一个道理.这里以a+=b和a=a+b为例做说明. (1)下面以一段Java程序为例,试 ...

  7. loadrunner脚本函数讲解

    一. get请求和post请求区别:web_link(get).web_submit_form(post)依赖上下文,web_url.web_submit_data不依赖上下文,建议使用web_url ...

  8. 抽象类练习(Job和TestJob)

    package com.Summer_0427.cn; /** * @author Summer * 根据抽象类完成以下题目 * 某软件公司对程序员的工作有一个总体的规定, * 不同的类型的程序员可以 ...

  9. 读书笔记---<<图解HTTP>>(一)

    一.了解Web及网络基础 1. 网络基础TCP/IP 通常使用的网络包括互联网都是在TCP/IP协议族的基础上运作的,而HTTP属于它内部的一个子集. 1.1 TCP/IP协议族 像这样吧与互联网关联 ...

  10. 搭建vue.js环境

    一.安装Node.js (以下安装环境均为win10) 下载链接:https://nodejs.org/en/download/ 官网给出了两个版本,LTS和Curren.字面意思是推荐大多数用户使用 ...