【BZOJ4818】【SDOI2017】序列计数 [矩阵乘法][DP]
2017-04-13 17:07
337 查看
序列计数
Time Limit: 30 Sec Memory Limit: 128 MB[Submit][Status][Discuss]
Description
Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数。Alice还希望,这n个数中,至少有一个数是质数。Alice想知道,有多少个序列满足她的要求。Input
一行三个数,n,m,p。Output
一行一个数,满足Alice的要求的序列数量,答案对20170408取模。Sample Input
3 5 3Sample Output
33HINT
1<=n<=10^9,1<=m<=2×10^7,1<=p<=100Solution
先考虑容斥,用Ans=全部的方案数 - 一个质数都没有的方案,那么我们首先想到了一个暴力DP,令 f[i][j] 表示选了前 i 个数,%p时余数为 j 的方案数。那么显然 %p 同余的可以分为一类,那么就可以用矩阵乘法来优化这个DP了。
Code
#include<iostream> #include<string> #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> using namespace std; typedef long long s64; const int MaxM = 2e7+5; const int ONE = 105; const int MOD = 20170408; int n,m,p; int prime[1300005],p_num; int Record[ONE][2],a[ONE][ONE],b[ONE][ONE]; bool isp[MaxM]; inline int get() { int res=1,Q=1; char c; while( (c=getchar())<48 || c>57) if(c=='-')Q=-1; if(Q) res=c-48; while((c=getchar())>=48 && c<=57) res=res*10+c-48; return res*Q; } void Getp(int MaxN) { isp[1] = 1; for(int i=2; i<=MaxN; i++) { if(!isp[i]) prime[++p_num] = i; for(int j=1; j<=p_num, i*prime[j]<=MaxN; j++) { isp[i * prime[j]] = 1; if(i % prime[j] == 0) break; } } } void Mul(int a[ONE][ONE],int b[ONE][ONE],int ans[ONE][ONE]) { int record[ONE][ONE]; for(int i=0;i<p;i++) for(int j=0;j<p;j++) { record[i][j] = 0; for(int k=0;k<p;k++) record[i][j] = (s64)(record[i][j] + (s64)a[i][k]*b[k][j] % MOD) %MOD; } for(int i=0;i<p;i++) for(int j=0;j<p;j++) ans[i][j] = record[i][j]; } void Quickpow(int a[ONE][ONE],int b[ONE][ONE],int t) { while(t) { if(t&1) Mul(a,b,a); Mul(b,b,b); t>>=1; } } int Solve(int PD) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); for(int i=0;i<p;i++) for(int j=0;j<p;j++) b[i][j] = Record[((i-j)%p+p)%p][PD]; for(int i=0;i<p;i++) a[i][i] = 1; Quickpow(a,b,n); return a[0][0]; } int main() { n=get(); m=get(); p=get(); Getp(m); for(int i=1;i<=m;i++) { int x = i%p; Record[x][0]++; if(isp[i]) Record[x][1]++; } printf("%d",(Solve(0)-Solve(1)+MOD) % MOD); }View Code
相关文章推荐
- [BZOJ4818][Sdoi2017][容斥原理][矩阵优化DP]序列计数
- 【bzoj4818】[Sdoi2017]序列计数 矩阵乘法
- bzoj 4818 [Sdoi2017]序列计数 矩阵乘法优化dp+容斥
- BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法
- [BZOJ4818][SDOI2017]序列计数(矩阵加速dp)
- BZOJ 4818 [Sdoi2017]序列计数 ——矩阵乘法
- 【BZOJ 4818】 4818: [Sdoi2017]序列计数 (矩阵乘法、容斥计数)
- bzoj 4818 [Sdoi2017]序列计数(简单容斥+快速幂加速dp)
- bzoj4818 [Sdoi2017]序列计数(矩阵)
- bzoj 4818: [Sdoi2017]序列计数 动态规划+矩阵乘法
- BZOJ4818 [SDOI2017] 序列计数 【矩阵快速幂】
- [DP 倍增] BZOJ 4818 [Sdoi2017]序列计数
- 【BZOJ4818】[Sdoi2017]序列计数 DP+矩阵乘法
- BZOJ4818 [Sdoi2017]序列计数
- bzoj 4818: [Sdoi2017]序列计数
- 【bzoj4818】 Sdoi2017—序列计数
- 【bzoj4818】[Sdoi2017]序列计数
- BZOJ4818: [Sdoi2017]序列计数
- bzoj 4818: [Sdoi2017]序列计数(DP+矩阵快速幂)
- [BZOJ4818][SDOI2017]序列计数(DP+容斥原理+矩乘)