HDU --- 4686 【矩阵快速幂+求和】

传送门

思路: 这道题也是给了公式, 然后跟着公式推导, 也很容易的知道矩阵的构造, 注意的是在矩阵中把Sn加上, 这样就可以直接算出答案了.

AC Code

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define CLR(x) memset(x,0,sizeof(x))
#define ll long long int
#define PI acos(-1.0)
#define db double
#define mod 1000000007
using namespace std;
const int maxn=1e5+5;
const db eps=1e-6;
const int inf=1e9;
const ll INF=1e15;
int cas=1;
int ssize;
struct Ma
{
    ll a[10][10];

    void cc()
    {
        memset(a,0,sizeof(a));
    }
    Ma operator * (const Ma & b) const {
        Ma tmp;
        tmp.cc();
        for(int i=0;ifor(int j=0;jfor(int k=0;kreturn tmp;
    }
}res,x;

ll A0,AX,AY,B0,BX,BY;

void init()
{
    ssize = 5;
    res.cc();
    x.cc();
    for(int i=0;i1 ;

    x.a[0][0] = 1;
    x.a[1][0] = x.a[1][1] = AX*BX%mod;
    x.a[2][0] = x.a[2][1] = AX*BY%mod;  x.a[2][2] = AX%mod;
    x.a[3][0] = x.a[3][1] = BX*AY%mod;  x.a[3][3] = BX%mod;
    x.a[4][0] = x.a[4][1] = AY*BY%mod;  x.a[4][2] = AY%mod; x.a[4][3] = BY%mod;
    x.a[4][4] = 1;
        //构造矩阵.
 }

void qpow(ll n)
{
    while(n)
    {
         //printf("%lld\n",n);
        if(n&1) res = res * x;
        x = x*x ;
        n /= 2;
    }
}

int main()
{
    ll n;
    ll b[10];
    while(~scanf("%lld",&n)){
        scanf("%lld%lld%lld%lld%lld%lld",&A0,&AX,&AY,&B0,&BX,&BY);
        if(n == 0){       //注意特判等于0的时候, 否则会T.
            printf("0\n");
            continue;
        }
        b[0] = b[1] = A0*B0%mod;
        b[2] = A0%mod;
        b[3] = B0%mod;
        b[4] = 1;
        init();
        qpow(n-1);
        ll ans = 0;
        for(int i=0;i0] * b[i]);
            ans %= mod;
        }
        printf("%lld\n",ans);
    }

}

你可能感兴趣的:(矩阵快速幂/快速乘)