题解:UVA10870 Recurrences

UVA10870 题解

题面

原题传送门

题意

考虑以下形式的递推函数:

f(n)=a1f(n1)+a2f(n2)+a3f(n3)++adf(nd)(当 n>d 时)

其中 a1,a2,,ad 是任意常数。

  • 递推的阶数 d(称为递推的阶数),
  • d 个系数 a1,a2,,ad
  • 初始值 f(1),f(2),,f(d)

输入将给定这些数字,以及两个整数 nm。程序的任务是计算 f(n)m 取模的结果。

思路

这题是裸的矩阵加速。(应该没有蓝吧……)

首先我们有如下式子。

  • fi=a1×fi1+a2×fi2++ad×fid
  • fi1=1×fi1+0×fi2++0×fid
  • fi2=0×fi1+1×fi2++0×fid
  • fid+1=0×fi1+0×fi2++1×fid+1+0×fid

把这些式子化成矩阵。

[fifi1fid+2fid+1]=[a1a2ad1ad100001000010]×[fi1fi2fid+1fid]

于是要是 nd 的话直接输出 fn,否则我们就可以用矩阵快速幂加速。

[fifn1fnd+2fnd+1]=[a1a2ad1ad100001000010]nd×[fdfd1f2f1]

注意,在输入答案矩阵的时候是倒着输入的,不要搞错了。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
ll k,n,mod;
class matrix{
    public:
    ll g[25][25];
    matrix(){for(int i=0; i<k; i++) for(int j=0; j<k; j++)g[i][j]=0;}
    void clear(){for(int i=0; i<k; i++) for(int j=0; j<k; j++)g[i][j]=0;}
    void print(){for(int i=0; i<k; i++){for(int j=0; j<k; j++)cout<<g[i][j]<<' ';cout<<endl;}}
    matrix& operator = (const matrix& x){for(int i=0; i<k; i++) for(int j=0; j<k; j++) g[i][j]=x.g[i][j];return *this;}
    matrix operator * (const matrix& x){matrix c;for(int i=0; i<k; i++) for(int j=0; j<k; j++) for(int l=0; l<k; l++) (c.g[i][j]+=g[i][l]*x.g[l][j]%mod)%=mod;return c;}
    matrix operator ^ (const ll& x){matrix res,a=*this;ll b=x;for(int i=0; i<k; i++) res.g[i][i]=1;while(b){if(b&1)res=res*a;a=a*a;b>>=1;}return res;}
};
void write(ll n){if(n<0){putchar('-');write(-n);return;}if(n>9)write(n/10);putchar(n%10+'0');}
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
int main(){
    while(1){
        k=read();n=read();mod=read();
        if(!k&&!n&&!mod) return 0;
        matrix f,ans;
        for(int i=1; i<k; i++) f.g[i][i-1]=1;
        for(int i=0; i<k; i++) f.g[0][i]=read();
        for(int i=k-1; ~i; i--) ans.g[i][0]=read();
        if(n<=k){write(ans.g[k-n][0]%mod);putchar('\n');continue;}
        f=f^(n-k);ans=f*ans;
        write(ans.g[0][0]);putchar('\n');
    }
}
posted @   naroto2022  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示
战斗是残酷的,无法做出多余的考虑!