Light1052 String Growth【矩阵快速幂】

xiaoxiao2021-02-28  59

题意:一个字符串由a,b组成,字符串转化为下一个的规则为:a->b,b->ab,告诉你,第n个、第m个字符串的长度,算第k个的长度

思路:这个变化规则,我们可以发现长度的变化是斐波拉契数列,我们设第1项有q个a,p个b,往下推,q、p前面的系数也是斐波拉契数列,我们快速幂算第n、m项q、p的前的系数,a1*q+b1*p = 第n项的长度,解二元一次方程,算出q、p算第k项

解方程:ax + by = m;cx + dy = n

有无实数解:yu1 = (md-bn) % (ad-bc);yu2 = (mc-an) % (bc-ad); 判断余数,余数都为0,有解

解:x = (md-bn) / (ad-bc);y = (mc-an)/(bc-ad)

#include<stdio.h> #include<iostream> #include<string.h> #include<string> #include<stdlib.h> #include<math.h> #include<vector> #include<list> #include<map> #include<stack> #include<queue> #include<algorithm> #include<numeric> #include<functional> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int maxn = 5; typedef long long ll; int MOD,N; struct data { ll s[maxn][maxn]; }res,tp; void init() { N = 2; memset(res.s,0,sizeof res.s); memset(tp.s,0,sizeof tp.s); res.s[1][1] = 1;res.s[2][2] = 1; tp.s[1][1] = 1;tp.s[1][2] = 1; tp.s[2][1] = 1;tp.s[2][2] = 0; } struct data mat(struct data &x,struct data &y) { struct data temp; memset(temp.s,0,sizeof temp.s); for(int i = 1; i <= N; i++) { for(int j = 1; j <= N; j++) { for(int k = 1; k <= N; k++) { temp.s[i][j] = (temp.s[i][j] + x.s[i][k] * y.s[k][j]) % MOD; } } } return temp; } struct data mpow(struct data &a,ll b) { while(b) { if(b&1) res = mat(res,a); b >>= 1; a = mat(a,a); } return res; } int main(void) { ll n,m,x,y,k,q1,q2,p1,p2,p,q; int kase = 1,T; MOD = 1e9+7; scanf("%d",&T); while(T--) { scanf("%lld%lld%lld%lld%lld",&n,&x,&m,&y,&k); if(n > m) { swap(n,m); swap(x,y); } q1 = q2 = p1 = p2 = 0; flag = 1; init(); if(n == 1) { q1 = 1; p1 = 1; } else { res = mpow(tp,n-2); q1 = ( res.s[1][1] * 1 + res.s[1][2] * 1 ) % MOD; p1 = ( res.s[1][1] * 2 + res.s[1][2] * 1 ) % MOD; } init(); if(m == 1) { q2 = 1; p2 = 1; } else { res = mpow(tp,m-2); q2 = ( res.s[1][1] * 1 + res.s[1][2] * 1 ) % MOD; p2 = ( res.s[1][1] * 2 + res.s[1][2] * 1 ) % MOD; } printf("Case %d: ",kase++); if( (x*p2-p1*y)%(q1*p2-p1*q2) || (x*q2-q1*y)%(p1*q2-q1*p2) ) printf("Impossible\n"); else { q = (x*p2-p1*y)/(q1*p2-p1*q2); p = (x*q2-q1*y)/(p1*q2-q1*p2); if(q < 0 || p < 0) printf("Impossible\n"); else { init(); ll ans; if(k == 1) ans = q+p; else { res = mpow(tp,k-2); ans = res.s[1][2] * (p+q)%MOD + res.s[1][1] * (2*p+q)%MOD; } ans %= MOD; printf("%lld\n",ans); } } } return 0; }

转载请注明原文地址: https://www.6miu.com/read-85685.html

最新回复(0)