Light1052 String Growth【矩阵快速幂】

来源:互联网 发布:淘宝app怎么开店 编辑:程序博客网 时间:2024/05/08 02:06

题意:一个字符串由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;}


原创粉丝点击