数列 题解

题面

下面数列的第 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];
}

 

posted @ 2019-10-27 14:24  神之右大臣  阅读(259)  评论(0编辑  收藏  举报