ARC071_F 题解
RMJ 已经炸了好久了,什么时候能修好啊……
题意简述
定义“好”的序列
- 所有项都是
中的正整数。 - 第
项及之后的所有项都相等。 - 对每一个
,满足 两两之间都相等。
给出
题目分析
与其他题解差不多,仍是采用 DP。设
然后考虑状态转移,分三种情况:
-
:方案数直接为 。 -
:那么 都确定为 ,方案数为 。特别地,对 ,我们令 ,所以原式实质上等于 。 -
:则 及之后的所有项都必须相同。而 和 可以随便填。方案数为 。
综上,
考虑更优的做法。我们发现计算这个递推式其实可以很方便地用矩阵优化。初步设计答案矩阵为
为了将其递推到
我们一列一列进行解释:
第
第
第
第
这样用矩阵快速幂做确实是可行的,但我们会发现
考虑优化。首先,
相应地改变转移矩阵:
这样程序的常数就会小不少,总时间复杂度为
代码实现
#include<bits/stdc++.h> using namespace std; const int mod=1000000007; int n; struct matrix { int n,m; int a[5][5]; void init(int k) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(i!=j) a[i][j]=0; else a[i][j]=k; } friend matrix operator *(matrix a,matrix b)//矩阵乘法 { matrix c; c.n=a.n,c.m=a.m; c.init(0); for(int i=1;i<=a.n;i++) for(int j=1;j<=b.m;j++) for(int k=1;k<=a.m;k++) c.a[i][j]=(c.a[i][j]+1ll*a.a[i][k]*b.a[k][j]%mod)%mod; return c; } friend matrix operator ^(matrix a,int b)//矩阵快速幂 { matrix res; res.n=res.m=a.n; res.init(1); for(;b;b>>=1) { if(b&1) res=res*a; a=a*a; } return res; } }fs,tr; int main() { scanf("%d",&n); if(n==1) { printf("1"); return 0; }//特判 1 fs.n=1,fs.m=tr.n=tr.m=4; fs.a[1][1]=1ll*n*n%mod,fs.a[1][2]=n,fs.a[1][3]=1ll*n*n%mod,fs.a[1][4]=mod-1;//初始答案矩阵,注意 -1 是 mod-1 tr.init(0); tr.a[1][1]=tr.a[1][2]=tr.a[1][3]=tr.a[3][1]=tr.a[3][3]=tr.a[4][3]=tr.a[4][4]=1,tr.a[2][1]=mod-1;//转移矩阵 tr=tr^(n-2);//计算转移矩阵的幂 fs=fs*tr;//得到最终答案矩阵 printf("%d",fs.a[1][1]); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!