HDU - 618(暴搜+遞推+矩陣快速冪)

一種找規律的方法,先暴搜找出前幾個值,再多次循環找表達式係數,流批
https://www.cnblogs.com/yzm10/p/9313916.html

//#pragma comment(linker, "/STACK:10240000000000,10240000000000")
#include<bits/stdc++.h>

#define debug(x) cout <<#x<<" = "<<x<<endl
#define gg cout <<"---------------QAQ---------------"<<endl
#define fi first
#define se second
#define pb push_back
#define SZ(x) ((int)x.size())
#define ll  long long
#define L(i,u) for (register int i=head[u]; i; i=nxt[i])
#define rep(i,a,b) for (register int i=(a); i<=(b); i++)
#define per(i,a,b) for (register int i=(a); i>=(b); i--)
#define inf 0x3f3f3f3f
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef unsigned int ui;
typedef pair<int,int> pii;
typedef vector<int> Vi;
template<class T> inline void read(T &x){
	x=0; char c=getchar(); int f=1;
	while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
	while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
const int N = 166666, maxn = 1666666;
void FAST(){ios::sync_with_stdio(false);cin.tie(0);}
const ll mod = 1000000007;
struct mat {
	ll a[10][10];
};
ll mp[5][5] = {
	0,0,0,0,0,
	0,1,5,1,-1,
	0,1,0,0,0,
	0,0,1,0,0,
	0,0,0,1,0,
};
mat operator *(mat x, mat y) //重載乘運算
{
	mat ans;
	memset(ans.a, 0, sizeof(ans.a));
	for(int i = 1; i <= 4; ++i) 
		for(int j = 1; j <= 4; ++j)
			for(int k = 1; k <= 4; ++k) 
	ans.a[i][j] = (ans.a[i][j]+x.a[i][k]*y.a[k][j]+mod)%mod;
	return ans;
}
mat init(mat x)
{
	for(int i = 1; i <= 4; ++i)
		for(int j = 1; j <= 4; ++j)
			x.a[i][j] = mp[i][j];
	return x;
}
mat mod_pow(mat a, ll n)
{
	mat t = init(t);
	while(n) {
		if(n&1) a = t*a;
		t = t*t;
		n>>=1;
	}
	return a;
}

int main()
{
	ll n;
	while(~scanf("%lld", &n)) {
		ll ans = 0;
		if(n == 1) ans = 1;
		else if(n == 2) ans = 5;
		else if(n == 3) ans = 11;
		else if(n == 4) ans = 36;
		else {
			mat f;
			f.a[1][1] = 36, f.a[2][1] = 11;
			f.a[3][1] = 5, f.a[4][1] = 1;
			f = mod_pow(f, n-4);
			ans = f.a[1][1];
		}
		printf("%lld\n", ans);
	}
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章