[题解]

官方题解就两句话。

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

前导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. 雅虎天气API调用

    雅虎天气API调用: 1.调用方法:http://weather.yahooapis.com/forecastrss?w=2502265&u=c,绿色字体为城市代号,u=c表示取摄氏度. 2. ...

  2. MySql(三):MyISAM和InnoDB区别详解

    MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良.虽然性能极佳,但却有一个缺点 ...

  3. hdu 2066 一个人的旅行(dijkstra)

    一个人的旅行 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  4. swift 继承和构造器

    继承 class Vehicle { var numberOfWheels: Int var maxPassengers: Int func description() -> String { ...

  5. 处理图片(updated)

    高像素的图片,比如分辨率为 7712x4352 的照片,当加载到一个 bitmap 中时会占用相当大的内存. 每个像素会占用 4个字节的内存,所以当没有被压缩时,全部的图片会占用 12800万字节(约 ...

  6. dubbo异步调用三种方式

    异步通讯对于服务端响应时间较长的方法是必须的,能够有效地利用客户端的资源,在dubbo中,消费端<dubbp:method>通过 async="true"标识. < ...

  7. Android中<uses-sdk>属性和target属性分析

    1. 概要 <uses-sdk> 用来描述该应用程序可以运行的最小和最大API级别,以及应用程序开发者设计期望运行的平台版本.通过在manifest清单文件中添加该属性,我们可以更好的控制 ...

  8. trk压力测试工具(测试tcp)

    wrk 是web站点压力测试工具 针对tcp协议的压力测试工具,没有找到合适的. 自己写一个,起名 trk.

  9. Netty系列之Netty百万级推送服务设计要点(转)

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  10. CentOS 7 上systemctl 的用法

    我们对service和chkconfig两个命令都不陌生,systemctl 是管制服务的主要工具, 它整合了chkconfig 与 service功能于一体. systemctl is-enable ...