[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的方案数,矩阵快速幂即可. 另一种方法 ...
随机推荐
- 【BZOJ4542】[Hnoi2016]大数 莫队
[BZOJ4542][Hnoi2016]大数 Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个 ...
- java操作文件流对象
所有流对象 InputStream 字节流 FileInputStream 字节流 专门读写非文本文件的 BufferedInputStream 高效流 OutPutS ...
- 不怕慢 就怕站 不怕单线程 不怕 裸露ip
import sys import os import requests import threading from time import sleep from bs4 import Beautif ...
- Python菜鸟之路:Python基础-内置函数补充
常用内置函数及用法: 1. callable() def callable(i_e_, some_kind_of_function): # real signature unknown; restor ...
- MySQL时间函数-获取当前时间-时间差
MySQL中获取当前时间为now(),不同于sqlserver getdate(). SQLServer转MySQL除变化top 1 -> limit 1之后报错: limit [Err] 15 ...
- Django APP之contenttypes简单应用
Conttenttypes介绍 当你看到contenttype你是不是想到了请求头的contenttype? 但是 此contenttypes不是请求头Content-Type而是Django自带的a ...
- linux c编程:信号(一)
信号是软件中断,很多比较重要的应用程序都需要处理信号.并且信号提供了一种处理异步事件的方法.如终端用户键入中断键,会通过信号机制停止一个程序,或及早终止管道中的下一个程序 很多条件都可以产生信号,比如 ...
- angular中按需加载js
按需加载估计是大家在使用angular之后最想解决的问题吧,因为angular的依赖机制,导致了必须在第一次加载的时候就加载所有js文件,小项目还好,稍大一点的项目如果有上百个js文件,不管是从效率还 ...
- 1django 视图与网址
创建一个项目,名字叫mysite django-admin startproject mysite(项目名) 成功后,看到如下样式 mysite ├── manage.py └── mysite ├─ ...
- eclipse---个人设置
window---- preferences -----修改背景颜色 -----修改字体 ----修改窗口主题 ----设置编码 -----设置编译环境 ----设置web项目JDK编译的版本 --- ...