4818: [Sdoi2017]序列计数

Time Limit: 30 Sec  Memory Limit: 128 MB

Description

Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数。Alice还希望
,这n个数中,至少有一个数是质数。Alice想知道,有多少个序列满足她的要求。

Input

一行三个数,n,m,p。
1<=n<=10^9,1<=m<=2×10^7,1<=p<=100

Output

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

Sample Input

3 5 3

Sample Output

33

月考后日常颓水题,好久没有1A了,可能SDOI比较良心
SBDP,D[i]表示和为i的方案数,用所有的减去没有素数的,写出方程发现可以矩阵转移,然后乱敲

 #include<bits/stdc++.h>
using namespace std;
template <class _T> inline void read(_T &_x) {
int _t; bool flag = false;
while ((_t = getchar()) != '-' && (_t < '' || _t > '')) ;
if (_t == '-') _t = getchar(), flag = true; _x = _t - '';
while ((_t = getchar()) >= '' && _t <= '') _x = _x * + _t - '';
if (flag) _x = -_x;
}
using namespace std;
typedef long long LL;
const int mod = ;
const int maxv = ;
struct Mat {
int n, m, a[maxv][maxv];
Mat() {}
Mat(int x, int y):n(x), m(y) {
for (register int i = , j; i < n; ++i)
for (j = ; j < m; ++j)
a[i][j] = ;
}
inline void init() {for (int i = ; i < n; ++i) a[i][i] = ; }
inline Mat operator * (Mat B) {
Mat C(n, B.m);
for (register int i = , j, k; i < n; ++i)
for (j = ; j < B.m; ++j)
for (k = ; k < m; ++k) {
C.a[i][j] += (int)((LL)a[i][k] * B.a[k][j] % mod);
if (C.a[i][j] >= mod) C.a[i][j] -= mod;
}
return C;
}
inline Mat operator ^ (int t) {
Mat res(n, m), tmp = *this; res.init();
while (t) {
if (t & ) res = res * tmp;
tmp = tmp * tmp, t >>= ;
}
return res;
}
};
const int maxp = ;
const int maxm = ;
int n, m, p;
int cnt_p[maxp], cnt_n[maxp];
bool vis[maxm];
int prime[maxm / ], pcnt;
inline void Init() {
cnt_p[ % p] = ;
for (register int i = , j; i <= m; ++i) {
if (!vis[i]) {
prime[++pcnt] = i;
} else {
++cnt_p[i % p];
}
for (j = ; j <= pcnt && i * prime[j] <= m; ++j) {
vis[i * prime[j]] = true;
if (i % prime[j] == ) break;
}
}
int tmpa = m / p, tmpb = m % p;
for (register int i = ; i < p; ++i) {
cnt_n[i] = tmpa;
cnt_n[i] += (i && i <= tmpb);
}
}
inline int getres(Mat &a) {
Mat x(p, );
x.a[][] = ;
return ((a ^ n) * x).a[][];
}
int main() {
//freopen();
//freopen();
read(n), read(m), read(p);
Init();
Mat a(p, p), b(p, p);
for (int i = , j, to; i < p; ++i) {
for (j = ; j < p; ++j) {
to = i + j;
if (to >= p) to -= p;
a.a[i][to] = cnt_n[j];
b.a[i][to] = cnt_p[j];
}
}
int ans = getres(a) - getres(b);
if (ans < ) ans += mod;
cout << ans << endl;
return ;
}

BZOJ4818 序列计数的更多相关文章

  1. [Bzoj4818]序列计数(矩阵乘法+DP)

    Description 题目链接 Solution 容斥原理,答案为忽略质数限制的方案数减去不含质数的方案数 然后矩阵乘法优化一下DP即可 Code #include <cstdio> # ...

  2. 【BZOJ4818】[Sdoi2017]序列计数 DP+矩阵乘法

    [BZOJ4818][Sdoi2017]序列计数 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望 ,这n个数 ...

  3. BZOJ4818 LOJ2002 SDOI2017 序列计数 【矩阵快速幂优化DP】*

    BZOJ4818 LOJ2002 SDOI2017 序列计数 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数. Alice还希 ...

  4. 【BZOJ4818】序列计数(动态规划,生成函数)

    [BZOJ4818]序列计数(生成函数) 题面 BZOJ 题解 显然是求一个多项式的若干次方,并且是循环卷积 或者说他是一个\(dp\)也没有问题 发现项数很少,直接暴力乘就行了(\(FFT\)可能还 ...

  5. 【BZOJ4818】【SDOI2017】序列计数 [矩阵乘法][DP]

    序列计数 Time Limit: 30 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Alice想要得到一个长度为n的序 ...

  6. [BZOJ4818][SDOI2017]序列计数(动规+快速幂)

    4818: [Sdoi2017]序列计数 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 972  Solved: 581[Submit][Status ...

  7. [bzoj4818][Sdoi2017]序列计数_矩阵乘法_欧拉筛

    [Sdoi2017]序列计数 题目大意:https://www.lydsy.com/JudgeOnline/problem.php?id=4818. 题解: 首先列出来一个递推式子 $f[i][0]$ ...

  8. [Sdoi2017]序列计数 [矩阵快速幂]

    [Sdoi2017]序列计数 题意:长为\(n \le 10^9\)由不超过\(m \le 2 \cdot 10^7\)的正整数构成的和为\(t\le 100\)的倍数且至少有一个质数的序列个数 总- ...

  9. BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法

    BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望 ...

随机推荐

  1. 二叉树 c++

    树 非空树 有一个(root)根节点r 其余节点可分为m个互不相交的有限集(子树)T1....Tm 具有n个节点的树,具有(n-1)条连接(指针域),需要构成结构体,尽可能减少空间域的浪费,使用儿子兄 ...

  2. 微软职位内部推荐-Service Engineer for Office365

    微软近期Open的职位: Key Responsibilities: The Service Engineer in this team will be responsible for plannin ...

  3. Test Cases

    对于mode1 1 路径下一个空文件夹       结果:生成一个空的txt 2路径下一个文件夹内包含一个txt内容为abd(最基本的一个单词) 3路径下一个空文件夹一个txt,txt内容为以不同符号 ...

  4. 《linux内核设计与实现》第一章

    第一章Linux内核简介 一.unix 1.Unix的历史 Unix是现存操作系统中最强大和最优秀的系统. ——1969年由Ken Thompson和Dernis Ritchie的灵感点亮的产物. — ...

  5. Linux内核分析(第二周)

    操作系统是如何工作的? 一.总结:三大法宝 1.存储程序计算机 + 函数调用堆栈 + 中断机制 2.堆栈:C语言程序运行时候必须的一个记录调用路径和参数的空间(函数调用框架/提供局部变量/传递参数/保 ...

  6. 如何向妻子解释OOD

      前言 此文译自CodeProject上<How I explained OOD to my wife>一文,该文章在Top Articles上排名第3,读了之后觉得非常好,就翻译出来, ...

  7. Beta阶段冲刺五

    Beta阶段冲刺五 Task1:团队TSP 团队任务 预估时间 实际时间 完成日期 新增其他学院的爬虫 180 130 11.30 新增其他学院的数据库字段修改 180 160 12.1 新增其他学院 ...

  8. Ubuntu16解锁root

    administrator@rgqancy:~$ sudo passwd -u root [sudo] administrator 的密码: 对不起,请重试. [sudo] administrator ...

  9. MyBatis关联查询,一对一关联查询

    数据库E-R关系 实体类 public class City { Long id; String name; Long countryId; Date lastUpdate; } public cla ...

  10. Mybatis中jdbcType和javaType、typeHandler的对照关系

      JdbcType与Oracle.MySql数据类型对应列表,及 JdbcType Oracle MySql CHAR CHAR CHAR VARCHAR VARCHAR VARCHAR LONGV ...