【SDOI2017】序列计数
来源:互联网 发布:手工皮鞋店铺推荐知乎 编辑:程序博客网 时间:2024/06/16 01:39
题目描述
题目解析
呵呵,实际这是NOIP题你信吗?
如果不考虑包含质数的情况,因为p很小,我们不妨构建p*p的矩阵,然后对于(i,j)填有多少个数x使得(i+x)%p=j,最后矩阵快速幂一下就行了。
如果考虑质数我们便可以求出所有方案数再减去不包含质数的方案数。
代码
#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<cstdlib>#include<algorithm>#include<queue>#include<stack>using namespace std;#define MAXN#define MAXM 20000000#define INF 0x3f3f3f3ftypedef long long int LL;template<class T>void Read(T &x){ x=0;char c=getchar();bool flag=0; while(c<'0'||'9'<c){if(c=='-')flag=1;c=getchar();} while('0'<=c&&c<='9'){x=x*10+c-'0';c=getchar();} if(flag)x=-x;}const int MOD = 20170408;struct Matrix{ int n; LL data[105][105]; Matrix(){} Matrix(int _n){n=_n;memset(data,0,sizeof(data));} Matrix operator + (const Matrix &x)const{ Matrix ret=Matrix(n); for(int i=0;i<n;++i) for(int j=0;j<n;++j) ret.data[i][j]=data[i][j]+x.data[i][j]; return ret; } Matrix operator - (const Matrix &x)const{ Matrix ret=Matrix(n); for(int i=0;i<n;++i) for(int j=0;j<n;++j) ret.data[i][j]=data[i][j]-x.data[i][j]; return ret; } Matrix operator * (const Matrix &x)const{ Matrix ret=Matrix(n); for(int i=0;i<n;++i) for(int j=0;j<n;++j) for(int k=0;k<n;++k) ret.data[i][j]+=data[i][k]*x.data[k][j]; return ret; } Matrix operator % (const int mod)const{ Matrix ret=Matrix(n); for(int i=0;i<n;++i) for(int j=0;j<n;++j) ret.data[i][j]=data[i][j]%mod; return ret; }};Matrix quick_power(Matrix a,int p,int mod){ Matrix ret=Matrix(a.n); for(int i=0;i<ret.n;++i)ret.data[i][i]=1; while(p){ if(p&1)ret=ret*a%mod; a=a*a%mod; p>>=1; } return ret;}bool isprime[MAXM+10];int prime[MAXM+10],cnt;void init(int ed){ memset(isprime,1,sizeof(isprime)); cnt=0; isprime[1]=0; for(int i=2;i<=ed;++i){ if(isprime[i])prime[++cnt]=i; for(int j=1;j<=cnt&&prime[j]*i<=ed;++j){ isprime[prime[j]*i]=0; if(i%prime[j]==0)break; } }}int change[110];int main(){ //freopen("count.in","r",stdin); //freopen("count.out","w",stdout); int n,m,p; Read(n),Read(m),Read(p); init(m); Matrix origin=Matrix(p); memset(change,0,sizeof(change)); for(int i=1;i<=m;++i)++change[(i%p)]; for(int i=0;i<p;++i) for(int j=0;j<p;++j)origin.data[i][j]=change[((j-i)%p+p)%p]%MOD; Matrix ans1=quick_power(origin,n,MOD); origin=Matrix(p); memset(change,0,sizeof(change)); for(int i=1;i<=m;++i)if(!isprime[i])++change[(i%p)]; for(int i=0;i<p;++i) for(int j=0;j<p;++j)origin.data[i][j]=change[((j-i)%p+p)%p]%MOD; Matrix ans2=quick_power(origin,n,MOD); printf("%I64d\n",(ans1.data[0][0]-ans2.data[0][0]+MOD)%MOD);}/*1 2 1*/
阅读全文
1 0
- BZOJ4818 [Sdoi2017]序列计数
- 4818: [Sdoi2017]序列计数
- 【SDOI2017】序列计数
- BZOJ4818: [Sdoi2017]序列计数
- bzoj4818 [Sdoi2017]序列计数
- 【bzoj4818】[Sdoi2017]序列计数
- [DP 倍增] BZOJ 4818 [Sdoi2017]序列计数
- bzoj4818 [Sdoi2017]序列计数(矩阵)
- bzoj 4818: [Sdoi2017]序列计数 动态规划+矩阵乘法
- bzoj4818【SDOI2017】序列计数 矩阵快速幂+动态规划
- [BZOJ4818][Sdoi2017][容斥原理][矩阵优化DP]序列计数
- BZOJ 4818: [Sdoi2017]序列计数 (动态规划+矩阵乘法)
- bzoj 4818: [Sdoi2017]序列计数(DP+矩阵快速幂)
- [矩阵乘法] LOJ#2002. 「SDOI2017」序列计数
- 【动态规划20】bzoj4818[sdoi2017]序列计数(dp+矩阵快速幂)
- LOj #2002. 「SDOI2017」序列计数 (容斥+dp+矩阵快速幂)
- [BZOJ4818][SDOI2017]序列计数(DP+容斥原理+矩乘)
- bzoj 4818 [Sdoi2017]序列计数 矩阵乘法优化dp+容斥
- AOJ.832 路边骗局
- Ubuntu14.04在线安装配置Nginx
- Nodejs快速入门
- HttpServlet was not found on the Java
- 局域网访问本地localhost
- 【SDOI2017】序列计数
- Codeforces 103D Time to Raid Cowavans 分块思想
- js数组去重的三种常用方法总结
- sql用户和权限管理
- Android Java代码执行adb Shell命令
- 令你瞠目结舌的 JavaScript 代码技巧
- Android5.0以下 native方法监听app卸载
- 大学生程序设计邀请赛(华东师范大学)-D题(线段树+随机化)
- mybatis 调用存储过程