[题解]

官方题解就两句话。

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

前导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. 转 Android开发学习笔记:浅谈WebView

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://liangruijun.blog.51cto.com/3061169/647456 ...

  2. poj 1236 Network of Schools 【Tarjan】

    题目链接:http://poj.org/problem?id=1236 题意: 本题为有向图. 需解决两个问题: 1 须要给多少个点,才干传遍全部点. 2 加多少条边,使得整个图变得强连通. 使用Ta ...

  3. Django URL中r的意思

    例如: urlpatterns = patterns('', # ... (r'^time/plus/\d+/$', hours_ahead), # ... ) 正则表达式字符串的开头字母“r”. 它 ...

  4. 线程相关函数(5)-pthread_rwlock_rdlock(),pthread_rwlock_wrlock() 读写锁

    读共享,写独占 pthread_rwlock_tpthread_rwlock_initpthread_rwlock_destroypthread_rwlock_rdlockpthread_rwlock ...

  5. CXAnimation类

    #include "XAnimation.h" CXAnimation::CXAnimation(void) { m_strName = ""; m_nFram ...

  6. 【C语言】21-结构体

    C语言的核心部分都说得七七八八了,相信大家已经对C语言的基本数据类型(char\int\float).数组.指针都很熟悉了,今天来学习C语言中另外一种数据类型:结构体.在iOS开发中,结构体是经常用到 ...

  7. UIWebView和UICollectionViewController的使用

    UIWebView和UICollectionViewController的使用 UIWebView UIWebView是iOS内置的浏览器的控件, 可以浏览网页, 打开文档等 .系统自带的Safari ...

  8. Django rest_framework 认证源码流程

    一.请求到来后,都要先执行dispatch方法 dispatch根据请求方式的不同触发get/post/put/delete等方法 注意,APIView中的dispatch方法有很多的功能 def d ...

  9. 《Google软件测试之道》- Google软件测试介绍

    <Google软件测试之道>- Google软件测试介绍 2015-05-21 目录 1 质量与测试  2 角色  3 组织结构  4 爬.走.跑  5 测试类型  相关链接 与Micro ...

  10. eclipse生成export生成jar详解

    使用eclipse打jar包可能还有很多人不是很了解,今天特意测试整理一番. 打jar包有3种形式 JAR file               JAR Javadoc              ja ...