数列 题解
题面
下面数列的第 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];
}
众人皆醉我独醒,举世皆浊我独清

浙公网安备 33010602011771号