HDU 6395 - Sequence(分段+矩阵快速幂)

Sequence

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1857    Accepted Submission(s): 716

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define line cout<<"-------------------------"<<endl;
#define clr(a) memset(a,0,sizeof(a))

const int MAXN = 1e5+10;
const int INF = 0x3f3f3f3f;
const int Mod = 1e9+7;
const int N = 3;

ll t,n,a,b,c,d,p;

struct Matrix{//定义N*N的矩阵
    ll m[N][N];
}ans;
Matrix Mul(Matrix a,Matrix b){//定义矩阵乘法。
    Matrix c;
    memset(c.m,0,sizeof(c.m));
    for(int i=0;i<N;i++)
        for(int j=0;j<N;j++)
            for(int k=0;k<N;k++)
                c.m[i][j] += ((a.m[i][k]*b.m[k][j])%Mod + Mod)%Mod;
    return c;
}
Matrix fastm(Matrix a,int n) {//矩阵的快速幂
    Matrix res;//定义一个单位矩阵
    clr(res.m);
    for(int i=0;i<3;i++) res.m[i][i] = 1;//利用单位矩阵求解
    while(n){//快速幂
        if(n&1)
            res = Mul(res,a);
        n>>=1;
        a = Mul(a,a);
    }
    return res;//求出a^n
}

int main(){
    scanf("%lld",&t);
    while(t--){
        scanf("%lld%lld%lld%lld%lld%lld",&a,&b,&c,&d,&p,&n);
        clr(ans.m);
        ans.m[0][0] = d;ans.m[0][1] = c;
        ans.m[1][0] = ans.m[2][2] = 1;
        int flag = 0;
        if(n == 1){
            printf("%lld\n",a); continue;

        }
        if(n == 2){
            printf("%lld\n",b); continue;
        }
        for(int i=3;i<=n;){
            if(p/i == 0){//最后的部分
                Matrix w = ans;
                w = fastm(w,n-i+1);
                ll cnt = w.m[0][0]*b%Mod + w.m[0][1]*a%Mod + w.m[0][2]%Mod;
                cnt %= Mod;
                printf("%lld\n",cnt);
                flag = 1;break;
            }
            int j = min(n,p/(p/i));
            Matrix w = ans;
            w.m[0][2] = p/i;
            w = fastm(w,j-i+1);
            ll u = (w.m[1][0]*b + w.m[1][1]*a + w.m[1][2]) % Mod;
            ll v = (w.m[0][0]*b + w.m[0][1]*a + w.m[0][2]) % Mod;
            a = u;b = v;//更新
            i = j+1;
        }
        if(!flag)   printf("%lld\n",b);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/l18339702017/article/details/81704447
今日推荐