Matrix_QP(A_2SeqSum)

hdu_4686

题目大意:给出an,bn的递推,求ai*bi(i=0,1,……n-1)的和(an=a(n-1)*Ax+Ay, bn=b(n-1)*Bx+Bya0=A0, b0=B0, Ax,Bx,Ay,By已知)。
题解:矩阵快速幂不用说了,式子也好推,开了ll基本没有坑点,奇葩的是这题是做连通分量做到的,有丶意思。


#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

typedef long long ll;
const int N = 6;
const int MOD = 1e9 + 7;

ll A0, B0, Ax, Bx, Ay, By;
ll p, q, r, s;

struct M
{
	ll mat[N];
	M(){}
	M( int _ )
	{
		mat[1] = A0*B0%MOD;
		mat[2] = A0; mat[3] = B0;
		mat[4] = 1;
		mat[5] = A0*B0%MOD;
	}
};

struct _M
{
	ll mat[N][N];
	_M(){}
	_M( int _ )
	{
		mat[1][1] = p; mat[1][2] = q; mat[1][3] = r; mat[1][4] = s; mat[1][5] = 0;
		mat[2][1] = mat[2][3] = mat[2][5] = 0; mat[2][2] = Ax%MOD; mat[2][4] = Ay%MOD;
		mat[3][1] = mat[3][2] = mat[3][5] = 0; mat[3][3] = Bx%MOD; mat[3][4] = By%MOD;
		mat[4][1] = mat[4][2] = mat[4][3] = mat[4][5] = 0; mat[4][4] = 1;
		mat[5][1] = p; mat[5][2] = q; mat[5][3] = r; mat[5][4] = s; mat[5][5] = 1;
	}
};

void init()
{
	p = Ax*Bx%MOD;
	q = Ax*By%MOD;
	r = Bx*Ay%MOD;
	s = Ay*By%MOD;
}

M M12( M a, _M b )
{
	M c;
	memset(c.mat,0,sizeof(c.mat));
	for ( int i = 1; i < N; i ++ )
	{
		ll cur = 0;
		for ( int j = 1; j < N; j ++ )
			cur += (a.mat[j]%MOD*b.mat[i][j]%MOD)%MOD;
		
		c.mat[i] = cur % MOD;
	}
	return c;
}
_M M22( _M a, _M b )
{
	_M c;
	memset(c.mat,0,sizeof(c.mat));
	for ( int i = 1; i < N; i ++ )
	{
		for ( int j = 1; j < N; j ++ )
		{
			ll cur = 0;
			for ( int k = 1; k < N; k ++ )
				cur += (a.mat[i][k]%MOD*b.mat[k][j]%MOD)%MOD;
			c.mat[i][j] = cur % MOD;
		}
	}
	return c;
}

M qp( M a, _M b, ll c )
{
	while ( c )
	{
		if ( c & 1 ) a = M12( a, b );
		c >>= 1;
		b = M22(b,b);
	}
	return a;
}

int main()
{
	ll m;
	while ( ~scanf("%lld", &m) )
	{
		scanf("%lld%lld%lld", &A0, &Ax, &Ay);
		scanf("%lld%lld%lld", &B0, &Bx, &By);
		
		if ( !m ) puts("0");
		else if ( m == 1 )
		{
			ll now = A0%MOD*B0%MOD%MOD;
			printf("%lld
", now);
		}
		else
		{
			init();
			M ans(1);
			_M base(1);
		/*	for ( int i = 1; i < N; i ++)
				cout << ans.mat[i] << endl;
				
			for ( int i = 1; i < N; i ++ )
			{
				for ( int j = 1; j < N; j ++ )
					cout << base.mat[i][j] << " ";
				cout << endl;
			}
		*/
			ans = qp( ans, base, m-1);
			printf("%lld
", (ans.mat[5]%MOD+MOD)%MOD);
		}
	}
	return 0;
}

原文地址:https://www.cnblogs.com/FormerAutumn/p/9634682.html