[SDOI 2017] 序列计数
[题目链接]
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] 序列计数的更多相关文章
- [BZOJ 4818] [SDOI 2017] 序列计数
Description Alice想要得到一个长度为 \(n\) 的序列,序列中的数都是不超过 \(m\) 的正整数,而且这 \(n\) 个数的和是 \(p\) 的倍数. Alice还希望,这 \(n ...
- BZOJ4818 序列计数
4818: [Sdoi2017]序列计数 Time Limit: 30 Sec Memory Limit: 128 MB Description Alice想要得到一个长度为n的序列,序列中的数都是 ...
- [BZOJ4818][SDOI2017]序列计数(动规+快速幂)
4818: [Sdoi2017]序列计数 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 972 Solved: 581[Submit][Status ...
- [Sdoi2017]序列计数 [矩阵快速幂]
[Sdoi2017]序列计数 题意:长为\(n \le 10^9\)由不超过\(m \le 2 \cdot 10^7\)的正整数构成的和为\(t\le 100\)的倍数且至少有一个质数的序列个数 总- ...
- BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法
BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望 ...
- HDU 6348 序列计数 (树状数组 + DP)
序列计数 Time Limit: 4500/4000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Subm ...
- luogu3702-[SDOI2017]序列计数
Description Alice想要得到一个长度为nn的序列,序列中的数都是不超过mm的正整数,而且这nn个数的和是pp的倍数. Alice还希望,这nn个数中,至少有一个数是质数. Alice想知 ...
- 【BZOJ 4818】 4818: [Sdoi2017]序列计数 (矩阵乘法、容斥计数)
4818: [Sdoi2017]序列计数 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 560 Solved: 359 Description Al ...
- P3702 [SDOI2017]序列计数
P3702 [SDOI2017]序列计数 链接 分析: 首先可以容斥掉,用总的减去一个质数也没有的. 然后可以dp了,f[i][j]表示到第i个数,和在模p下是j的方案数,矩阵快速幂即可. 另一种方法 ...
随机推荐
- 【BZOJ4358】permu kd-tree
[BZOJ4358]permu Description 给出一个长度为n的排列P(P1,P2,...Pn),以及m个询问.每次询问某个区间[l,r]中,最长的值域连续段长度. Input 第一行两个整 ...
- Office 365系列(二) -一些比较容易混淆的概念
上一篇比较简明地说了Office 365怎么注册使用,在继续探讨之前先讨论一些比较容易混淆的概念! 1. Office 365: 是微软云计划的一部分包括Exchange online, Lync ...
- NSURLSession各文件关系
NSURLSession 通过session创建任务 @property (class, readonly, strong) NSURLSession *sharedSession; + (NSU ...
- BZOJ1505: [NOI2004]小H的小屋
BZOJ1505: [NOI2004]小H的小屋 Description 小H发誓要做21世纪最伟大的数学家.他认为,做数学家与做歌星一样,第一步要作好包装,不然本事再大也推不出去. 为此他决定先在自 ...
- Netbeans8.0设置Consola字体并解决中文乱码问题
在Netbeans8.0上开发php,设置字体为Consola后.发现中文显示是乱码的.经过改动jre的配置文件成功攻克了这个问题. 1. 进入jdk安装文件夹下/jre/lib文件夹,找到fontc ...
- git push问题 objects/pack/tmp_pack_XXXXXX': Permission denied
1.上传时的权限问题 在执行git push origin master之后,上传过程中报出如下错误: objects/pack/tmp_pack_XXXXXX': Permission denied ...
- Office 2013“永久激活信息”备份
Office 2013“永久激活信息”备份还原简明教程及成功恢复的注意事项Office 2013永久激活后及时备份激活信息可以保证重装后快速激活.网上也有流行的各种备份工具,虽然操作简单,但是如果不理 ...
- Git——版本控制概论(一)
随着信息技术的发展,软件开发已不是小手工作坊,软件的规模和复杂度已经不再适合一个人单打独斗的开发了, 团队协作变得相当重要,如果没有VCS(版本控制系统Version Control System), ...
- Data Structure Array: Find the minimum distance between two numbers
http://www.geeksforgeeks.org/find-the-minimum-distance-between-two-numbers/ #include <iostream> ...
- Qt事件机制(是动作发生后,一种通知对象的消息,是被动与主动的总和。先处理自己队列中的消息,然后再处理系统消息队列中的消息)
Qt事件机制 Qt程序是事件驱动的, 程序的每个动作都是由幕后某个事件所触发.. Qt事件的发生和处理成为程序运行的主线,存在于程序整个生命周期. Qt事件的类型很多, 常见的qt的事件如下: 键盘事 ...