数列 题解
题面
下面数列的第 n 项:
f(0) = a0 ,f(1) = a1 ,f(2) = a2
f(n) = b×f(n − 1) + c×f(n − 2) + d×f(n − 3) + e (n ≥ 3)
输入格式
包含 1 行,共 8 个整数:a0、a 1、a 2、b、c、d、e、n。
输出格式
输出 f(n) 的后 18 位(后 18 位的前缀 0 需要输出,不足 18 位用 0 补齐)。
样例输入
1 2 3 4 5 6 7 3
样例输出
000000000000000035
数据范围
对于 30% 的数据,0 ≤ a0 ,a1 ,a2 ,b,c,d,e,n ≤ 10 6
对于 100% 的数据,0 ≤ a0 ,a1 ,a2 ,b,c,d,e,n ≤ 10 18
题解:
比较清晰的:矩阵加速递推可以解决掉这道题;
注意一个细节,由于两个long long范围内的数相乘会爆long long,所以要使用龟速乘;(如果你愿意写个什么高精,FFT都没有问题)
#include <bits/stdc++.h> #define inc(i,a,b) for(register int i=a;i<=b;i++) using namespace std; long long a[5][5],b[5][5],tmp[5][5]; long long p=1e18; long long haha(long long x,long long y) { long long res=0; while(y){ if(y&1) res=(res+x)%p; x=x*2%p; y/=2; } return res; } void cheng1() { memset(tmp,0,sizeof(tmp)); inc(j,1,4) inc(k,1,4) tmp[1][j]=(tmp[1][j]+haha(a[1][k],b[k][j])%p)%p; inc(i,1,4) a[1][i]=tmp[1][i]%p; } void cheng2() { memset(tmp,0,sizeof(tmp)); inc(i,1,4) inc(j,1,4) inc(k,1,4) tmp[i][j]=(tmp[i][j]+haha(b[i][k],b[k][j])%p)%p; inc(i,1,4) inc(j,1,4) b[i][j]=tmp[i][j]%p; } void JZKSM(long long b) { while(b){ if(b&1) cheng1(); cheng2(); b/=2; } } int ans[20]; int main() { long long a0,a1,a2,w,c,d,e,n; cin>>a0>>a1>>a2>>w>>c>>d>>e>>n; a[1][1]=a0,a[1][2]=a1,a[1][3]=a2,a[1][4]=e; b[2][1]=1;b[1][3]=d;b[2][3]=c;b[3][3]=w;b[4][3]=1;b[4][4]=1;b[3][2]=1; JZKSM(n-2); long long now=a[1][3]%p; memset(ans,0,sizeof(ans)); while(now){ ans[++ans[0]]=now%10; now/=10; } for(int i=18;i>=1;i--) cout<<ans[i]; }
众人皆醉我独醒,举世皆浊我独清