[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=4818

[算法]

考虑容斥 , 用有至少有一个质数的合法序列数 - 没有质数的合法序列数

这两个问题是等价的 , 为方便讨论 , 我们考虑前者该如何计算 :

用fi , j表示前i个数 , 模p余j的合法序列数

显然有fi , j = sigma{ fi - 1 , j - k }

矩阵优化即可

时间复杂度 : O(M + logN)

[代码]

#include<bits/stdc++.h>
using namespace std; #ifndef LOCAL
#define eprintf(...) fprintf(stderr , _VA_ARGS)
#else
#define eprintf(...) 42
#endif typedef long long ll;
typedef long double ld;
typedef vector< int > vi;
typedef pair<int , int> pii;
typedef pair<ll , int> pli;
typedef pair<ll , ll> pll;
typedef unsigned long long ull;
#define mp make_pair
#define fi first
#define se second
const int N = 2e7 + ;
const int P = ; struct Tmatrix {
int mat[][];
} a; int n , m , p , tot;
int prime[N] , sa[] , sb[];
bool lab[N] , f[N]; template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void read(T &x) {
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline void sieve( ) {
for (int i = ; i <= m; ++i) {
if (!f[i]) {
prime[++tot] = i;
lab[i] = true;
}
for (int j = ; j <= tot; ++j) {
int tmp = i * prime[j];
if (tmp > m) break;
f[tmp] = true;
if (i % prime[j] == ) break;
}
}
}
inline int sub(int x , int y) {
x -= y;
while (x < ) x += P;
return x;
}
inline void multipy(Tmatrix &a , Tmatrix b) {
Tmatrix c;
for (int i = ; i < p; ++i) {
for (int j = ; j < p; ++j) {
c.mat[i][j] = ;
}
}
for (int i = ; i < p; ++i) {
for (int j = ; j < p; ++j) {
for (int k = ; k < p; ++k) {
c.mat[i][j] = (c.mat[i][j] + 1ll * a.mat[i][k] * b.mat[k][j] % P) % P;
}
}
}
for (int i = ; i < p; ++i) {
for (int j = ; j < p; ++j) {
a.mat[i][j] = c.mat[i][j];
}
}
}
inline void qpow(Tmatrix &a , int n) {
Tmatrix b , res;
for (int i = ; i < p; ++i) {
for (int j = ; j < p; ++j) {
res.mat[i][j] = (i == j);
b.mat[i][j] = a.mat[i][j];
}
}
while (n > ) {
if (n & ) multipy(res , b);
multipy(b , b);
n >>= ;
}
for (int i = ; i < p; ++i) {
for (int j = ; j < p; ++j) {
a.mat[i][j] = res.mat[i][j];
}
}
}
inline int calc(int n , int type) {
for (int i = ; i < p; ++i) {
for (int j = ; j < p; ++j) {
int k = (i - j + p) % p;
a.mat[i][j] = type == ? sa[k] : sb[k];
}
}
qpow(a , n);
return a.mat[][];
} int main() { read(n); read(m); read(p);
sieve( );
for (int i = ; i <= m; ++i) {
sa[i % p] = (sa[i % p] + ) % P;
if (!lab[i]) sb[i % p] = (sb[i % p] + ) % P;
}
printf("%d\n" , sub(calc(n , ) , calc(n , ))); return ;
}

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

  1. [BZOJ 4818] [SDOI 2017] 序列计数

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

  2. BZOJ4818 序列计数

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

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

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

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

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

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

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

  6. HDU 6348 序列计数 (树状数组 + DP)

    序列计数 Time Limit: 4500/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Subm ...

  7. luogu3702-[SDOI2017]序列计数

    Description Alice想要得到一个长度为nn的序列,序列中的数都是不超过mm的正整数,而且这nn个数的和是pp的倍数. Alice还希望,这nn个数中,至少有一个数是质数. Alice想知 ...

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

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

  9. P3702 [SDOI2017]序列计数

    P3702 [SDOI2017]序列计数 链接 分析: 首先可以容斥掉,用总的减去一个质数也没有的. 然后可以dp了,f[i][j]表示到第i个数,和在模p下是j的方案数,矩阵快速幂即可. 另一种方法 ...

随机推荐

  1. 更改eclipse(myeclipse) author的默认名字(注释的作者)

    在eclipse/myeclipse中,当添加注释的作者选项时,@author 后边一般都会默认填充的你登录计算机的用户名.如何去修改呢:第一种方法:修改计算机登录的用户名(一般不实用)第二种方法:修 ...

  2. transport connector和network connector

    1 什么是transport connector 用于配置activemq服务器端和客户端之间的通信方式. 2 什么是network connector 用于配置activemq服务器之间的通信方式, ...

  3. zookeepeer ID生成器 (一)

    目录 写在前面 1.1. ZK 的分布式命名服务 1.1.1. 分布式 ID 生成器的类型 UUID方案 1.1.2. ZK生成分布式ID 写在最后 疯狂创客圈 亿级流量 高并发IM 实战 系列 疯狂 ...

  4. Django 之 admin组件使用&源码解析

    admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.可以在项目的 settings.py 中的 INSTALLED ...

  5. G20峰会将会给数字货币带来哪些影响?

    G20峰会对于全球经济有着举足轻重的影响,其成员人口占全球的2/3,国土面积占全球的60%,国内生产总值占全球的90%,贸易额占全球的75%……作为国际经济合作的主要平台,G20在引领和推动国际经济合 ...

  6. linux 中 用户管理 (composer 时不能root 遇到)

    linux 是支持多用户的,可以同时多个用户在线操作,这点与 Windows 不同. 在我们项目组 操作linux 服务器时,可进行多用户管理,并赋予不同权限,下面是我学习并用的比较频繁的命令: 1. ...

  7. 在C语言中使用syslog打印日志到日志文件

    参见 <unix 环境高级编程>第13 章 精灵进程 Syslog为每个事件赋予几个不同的优先级: LOG_EMERG——紧急情况 LOG_ALERT——应该被立即改正的问题,如系统数据库 ...

  8. vMware存储:SAN配置基础

    VMware存储不仅仅是将LUN映射给物理服务器这么简单.VMware vSphere允许系统管理员在一个物理机上创建多个虚拟机. 潜在的hypervisor和vSphere ESXi,能够使gues ...

  9. Django模型系统——ORM表结构对应关系

    对于数据库来说一般表结构只会有三种对应关系,分别是一对一.一对多和多对一,下面分别介绍: 1.一对多 何为一对多,例如一个学生只可能有一个班级,一个班级却又多个学生,班级表和学生表就是一对多的关系. ...

  10. MySQL服务器调优思路

    1.mysqladmin -uroot ext|awk '/Queries/{q=$4}/Threads_connected/{c=$4}/Threads_running/{r=$4}END{prin ...