BZOJ 4818: [Sdoi2017]序列计数 (动态规划+矩阵乘法)
来源:互联网 发布:谁是最可爱的人 知乎 编辑:程序博客网 时间:2024/05/22 07:09
来源:http://blog.csdn.net/qq_33229466/article/details/70055284
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=4818
分析
一眼容斥,用所有方案减去不含质数的方案。
设f[i,j]表示序列前i个数模p的余数为j时的方案数。f[i,j]=∑f[i−1,(j−k)modp]
构建矩阵然后快速幂即可。
求不含质数的方案同理。
在一开始建矩阵的时候我的复杂度是mp,发现会超时。但是注意到矩阵的每一列都是循环同构的,于是就可以先O(m)处理好一列,然后再构建其他列即可。
代码:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int M=20000005;const int P=105;const int MOD=20170408;int n,m,p,prime[M/10],tot,f[P];struct arr{int a[P][P];}ans,a;bool not_prime[M];void get_prime(int n){ not_prime[1]=1; for (int i=2;i<=n;i++) { if (!not_prime[i]) prime[++tot]=i; for (int j=1;j<=tot&&i*prime[j]<=n;j++) { not_prime[i*prime[j]]=1; if (i%prime[j]==0) break; } }}void mul(arr &c,arr a,arr b){ memset(c.a,0,sizeof(c.a)); for (int i=0;i<p;i++) for (int j=0;j<p;j++) for (int k=0;k<p;k++) c.a[i][j]=(c.a[i][j]+(LL)a.a[i][k]*b.a[k][j]%MOD)%MOD;}arr ksm(arr x,int y){ memset(ans.a,0,sizeof(ans.a)); for (int i=0;i<p;i++) ans.a[i][i]=1; while (y) { if (y&1) mul(ans,ans,x); mul(x,x,x);y>>=1; } return ans;}int solve1(){ for (int i=1;i<=m;i++) f[i%p]++; for (int j=1;j<=m;j++) a.a[(-j%p+p)%p][0]++; for (int i=1;i<p;i++) for (int j=0;j<p;j++) a.a[j][i]=a.a[(j-1+p)%p][i-1]; a=ksm(a,n-1); int ans=0; for (int i=0;i<p;i++) ans=(ans+(LL)f[i]*a.a[i][0]%MOD)%MOD; return ans;}int solve2(){ memset(f,0,sizeof(f)); for (int i=1;i<=m;i++) if (not_prime[i]) f[i%p]++; memset(a.a,0,sizeof(a.a)); for (int j=1;j<=m;j++) if (not_prime[j]) a.a[(-j%p+p)%p][0]++; for (int i=1;i<p;i++) for (int j=0;j<p;j++) a.a[j][i]=a.a[(j-1+p)%p][i-1]; a=ksm(a,n-1); int ans=0; for (int i=0;i<p;i++) ans=(ans+(LL)f[i]*a.a[i][0]%MOD)%MOD; return ans;}int main(){ scanf("%d%d%d",&n,&m,&p); get_prime(m); int x=solve1(),y=solve2(); printf("%d",(x-y+MOD)%MOD); return 0;}
阅读全文
0 0
- BZOJ 4818: [Sdoi2017]序列计数 (动态规划+矩阵乘法)
- bzoj 4818: [Sdoi2017]序列计数 动态规划+矩阵乘法
- bzoj 4818: [Sdoi2017]序列计数(DP+矩阵快速幂)
- bzoj 4818 [Sdoi2017]序列计数 矩阵乘法优化dp+容斥
- bzoj4818【SDOI2017】序列计数 矩阵快速幂+动态规划
- 【动态规划20】bzoj4818[sdoi2017]序列计数(dp+矩阵快速幂)
- [DP 倍增] BZOJ 4818 [Sdoi2017]序列计数
- [矩阵乘法] LOJ#2002. 「SDOI2017」序列计数
- bzoj4818 [Sdoi2017]序列计数(矩阵)
- 4818: [Sdoi2017]序列计数
- bzoj 4818 [Sdoi2017]序列计数(简单容斥+快速幂加速dp)
- 矩阵乘法(动态规划)
- bzoj 4037: [HAOI2015]Str 矩阵乘法&动态规划
- bzoj 1875: [SDOI2009]HH去散步 动态规划+矩阵乘法
- bzoj 5223. 【GDOI2018模拟7.12】B 动态规划+矩阵乘法
- BZOJ4818 [Sdoi2017]序列计数
- 【SDOI2017】序列计数
- BZOJ4818: [Sdoi2017]序列计数
- diss天地伟业
- werkzeug-Context Locals
- HTTP 中 GET 与 POST 的区别
- 图像恢复----Retinex算法详解
- uml图中的关系
- BZOJ 4818: [Sdoi2017]序列计数 (动态规划+矩阵乘法)
- eclipse常用快捷键
- LeetCode 198. House Robber
- android xmlns:tools用法
- IDEA如何将master合并到指定支代码
- cocos2d.3.10导入安卓项目相关问题笔记
- JAVA各种系统架构图及其简介
- 翻转单词顺序列
- Android 获取cache缓存的目录路径