[题解]

官方题解就两句话。

写了三个版本的不同分值代码。看代码吧。

前导1

//f[i][j][1/0]表示长为i,sum mod p=j,是否已经选了质数的方案数
#include<cstdio>
using namespace std;
const int mod=;
const int N=1e6+;
int tot,prime[N/];bool check[N];
int n,m,f[][N][];int p;
void pre(){
n=1e6;check[]=check[]=;
for(int i=;i<=n;i++){
if(!check[i]) prime[++tot]=i;
for(int j=;j<=tot&&i*prime[j]<=n;j++){
check[i*prime[j]]=;
if(!(i%prime[j])) break;
}
}
}
int main(){
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
pre();
scanf("%d%d%d",&n,&m,&p);
for(int i=;i<=m;i++) f[][i%p][!check[i]]++;
for(int i=,val;i<n;i++){
for(int j=;j<p;j++){
for(int k=;k<=m;k++){
val=(j+k)%p;
if(!check[k]){
f[i+&][val][]=(f[i+&][val][]+f[i&][j][]+f[i&][j][])%mod;
}
else{
f[i+&][val][]=(f[i+&][val][]+f[i&][j][])%mod,
f[i+&][val][]=(f[i+&][val][]+f[i&][j][])%mod;
}
}
}
for(int j=;j<p;j++){
f[i&][j][]=;
f[i&][j][]=;
}
}
printf("%d",f[n&][][]);
return ;
}

前导2

#include<cstdio>
using namespace std;
const int mod=;
const int N=1e6+;
int tot,prime[N/];bool check[N];
int n,m,p;
int f[][N];
int g[][N];
int sz[N];
void pre(){
n=1e6;check[]=check[]=;
for(int i=;i<=n;i++){
if(!check[i]) prime[++tot]=i;
for(int j=;j<=tot&&i*prime[j]<=n;j++){
check[i*prime[j]]=;
if(!(i%prime[j])) break;
}
}
}
int main(){
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
pre();
scanf("%d%d%d",&n,&m,&p);
//全集
for(int k=;k<=p;k++) sz[k]=m/p+(m%p>=k);sz[]=sz[p];
for(int i=;i<p;i++) f[][i]=sz[i];
for(int i=,val;i<n;i++){
for(int j=;j<p;j++){
for(int k=;k<p;k++){
val=(j+k)%p;
f[i+&][val]=(f[i+&][val]+sz[k]*f[i&][j])%mod;
}
}
for(int j=;j<p;j++) f[i&][j]=;
}
//不包含素数
for(int i=;i<=tot&&prime[i]<=m;i++) sz[prime[i]%p]--;
for(int i=;i<p;i++) g[][i]=sz[i];
for(int i=,val;i<n;i++){
for(int j=;j<p;j++){
for(int k=;k<p;k++){
val=(j+k)%p;
g[i+&][val]=(g[i+&][val]+sz[k]*g[i&][j])%mod;
}
}
for(int j=;j<p;j++) g[i&][j]=;
}
printf("%d",f[n&][]-g[n&][]);
return ;
}

AC代码

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int mod=;
const int N=;
const int M=2e7+;
int tot,prime[M/];bool check[M];
int n,m,p;
int sz[N];
struct matrix{
ll s[N];//降低常数
matrix(){
memset(s,,sizeof s);
}
}A,B;
matrix operator *(const matrix &a,const matrix &b){
matrix c;
for(int i=;i<p;i++){
// c.s[i]=0;
for(int k=;k<p;k++){
c.s[i]+=a.s[(i-k+p)%p]*b.s[k];
c.s[i]%=mod;
}
}
return c;
}
ll fpow(matrix a,ll p){
matrix res;
// for(int i=0;i<p;i++) res.s[i]=0;
res.s[]=;
for(;p;p>>=,a=a*a) if(p&) res=res*a;
return res.s[];
}
void pre(){
check[]=check[]=;
for(int i=;i<=m;i++){
if(!check[i]) prime[++tot]=i;
for(int j=;j<=tot&&i*prime[j]<=m;j++){
check[i*prime[j]]=;
if(!(i%prime[j])) break;
}
}
}
int main(){
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
scanf("%d%d%d",&n,&m,&p);
pre();
for(int k=;k<=p;k++) sz[k]=m/p+(m%p>=k);sz[]=sz[p];
for(int i=;i<p;i++) A.s[i]=sz[i];
for(int i=;i<=tot&&prime[i]<=m;i++) sz[prime[i]%p]--;
for(int i=;i<p;i++) B.s[i]=sz[i];
ll ans=(fpow(A,n)-fpow(B,n))%mod;if(ans<) ans+=mod;
printf("%lld",ans);
return ;
}

codevs 5964 [SDOI2017]序列计数的更多相关文章

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

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

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

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

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

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

  4. P3702 [SDOI2017]序列计数

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. C语言实现http get请求程序

    1.客户端程序: 向指定URL发送http请求, http://files.cnblogs.com/files/yyx1-1/httpclient01.7z 源码程序 2.服务器程序: 接收URL请求 ...

  2. 自定义规则,对List<Map<String,Object>> List<Object>进行排序

    package lltse.java.collection; import java.util.ArrayList; import java.util.Collections; import java ...

  3. QT实现右键快捷菜单

    [转自]:http://blog.csdn.net/rolland1989/article/details/5754575 QWidget及其子类都可有右键菜单,因为QWidget有以下两个与右键菜单 ...

  4. dom写xml

    1.引入包 import xml.dom.minidom 2.writexml方法 writexml(writer, indent, addindent, newl, encoding) writer ...

  5. python爬虫解析库之Beautifulsoup模块

      一 介绍 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会 ...

  6. vue中config/index.js:配置的详细理解

    当我们需要和后台分离部署的时候,必须配置config/index.js: 用vue-cli 自动构建的目录里面  (环境变量及其基本变量的配置) var path = require('path') ...

  7. IIS网站本机可以访问,局域网其他机器无法访问

    [开始]打开[控制面板],选择[WINDOWS 防火墙],进入 步骤阅读 2 在防火墙界面,选择左侧边栏的[高级设置] 步骤阅读 3 在弹出的高级安全Windows防火墙界面中,选择左侧边栏的[入站规 ...

  8. ar命令学习

    之前,学习Linux下使用静态库的时候涉及到了这三个命令: gcc -c my_strcpy.c my_strcmp.car rcs libmylib.a *.ogcc -o main main.c ...

  9. sqlite笔记(akaedu)

    1.创建sql表create table student(id integer primary key, name text, score integer): 2.插入一条记录insert into ...

  10. 如何让每个 WordPress 页面有不同的风格或者样式

    如果使用 page.php 来处理所有页面的外观的话,答案肯定是不行的,但是如果使用不同的 WordPress 页面模板,就可以自定义每个页面的外观了. 比如你博客的所有的页面除了“关于”这个页面之外 ...