1 条题解
-
0
自动搬运
来自洛谷,原作者为

ysner
这个家伙不懒,但也什么都没有留下搬运于
2025-08-24 21:37:57,当前版本为作者最后更新于2017-08-01 07:22:17,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
看到楼下的题解没画出矩阵图,而矩阵是矩阵快速幂最重要的一环,我就来补一发吧。
本题主要是构造矩阵,我们只需要把那一段式子看成两个前缀和相减, 然后就直接矩阵连乘。

直接对那个k+1阶矩阵快速幂即可,注意初始化矩阵为单位矩阵,即主对角线(左上到右下)都为1其他都为0。
另外,很多量要开long long。
当然,为了卡时间,我inline、register、读入优化齐用,卡到了63ms。。。膜拜12ms的rank 1。。。
#include<iostream> #include<cmath> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #define ll long long #define re register #define il inline using namespace std; int b[15]={},c[15]={},sum[15]={},K,p,ansn,ansm; ll n,m; il ll gi()//读入优化开long long,否则只有20分 { re ll x=0,t=1; re char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if(ch=='-') t=-1,ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar(); return x*t; } struct matrix//矩阵乘法标准模板 { int a[16][16]; matrix () { memset(a,0,sizeof(a)); } int *operator [](int x) { return a[x]; } matrix operator *(matrix &b) { matrix c; for (re int i=0;i<=K;i++) for (re int j=0;j<=K;j++) for (re int k=0;k<=K;k++) c[i][k]=(c[i][k]+1ll*a[i][j]*b[j][k])%p; return c; } }S,T; il void init() { for (re int i=0;i<K;i++) S[0][i]=b[i]; S[0][K]=sum[K-1]; for (re int i=1;i<=K;i++) for (re int j=0;j<=K;j++) S[i][j]=0; for (re int i=0;i<=K;i++) for (re int j=0;j<=K;j++) if (i==j+1) T[i][j]=1; else T[i][j]=0; for (re int i=0;i<K;i++) T[i][K-1]=T[i][K]=c[K-i-1]; T[K][K-1]=0;T[K][K]=1; } int main() { K=gi(); for (re int i=0;i<K;i++) b[i]=gi(),sum[i]=b[i]+sum[i-1]; for (re int i=0;i<K;i++) c[i]=gi(); m=gi();n=gi();p=gi(); m-=K+1;n-=K; if (m<=0) ansm=sum[m+K-1]; else { init(); while (m) { if (m&1) S=S*T; T=T*T; m>>=1; } ansm=S[0][K]; } if (n<=0) ansn=sum[n+K-1]; else { init(); while (n)//快速幂 { if (n&1) S=S*T; T=T*T; n>>=1; } ansn=S[0][K]; } printf("%d",(ansn-ansm+p)%p); return 0; }
- 1
信息
- ID
- 1492
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者