HDU 6395 Sequence 矩阵快速幂

版权声明:布呗之路的守望者 https://blog.csdn.net/hypHuangYanPing/article/details/81877920
/**
HDU 6395 Sequence 矩阵快速幂
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6395
题意:计算所给表达式的第n项的值
分析:对于所给 p/i 存在许多重复的数字分块思想+矩阵快速幂 
转换为每次求解  f[n]=c*f[n-2]+d*f[n-1]+nn nn为变量且每次变化的次数已知;
每次不断成块的进行更新即可;
*****tricks****
分类讨论n大于3的情况 每一块的数量必须大于3  
*/

#include<bits/stdc++.h>
#define ll long long
using namespace std;
/**********************************************Head-----Template****************************************/
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){ll gg=gcd(a,b);a/=gg;if(a<=LLONG_MAX/b) return a*b;return LLONG_MAX;}
/********************************Head----Temlate**********************************************/

const int mod=1e9+7;
const int maxn=1e6+7;

struct mat {
    ll a[3][3];
    mat() {
        memset(a, 0, sizeof(a));
    }
    mat operator *(const mat &M)const{
        mat res=mat();
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                for(int k=0;k<3;k++)
                    res.a[i][j]=(res.a[i][j]+a[i][k]*M.a[k][j])%mod;
            }
        }
        return res;
    }
}A,B;
mat qpow(mat M,ll n){
    mat res=mat();
       for(int i=0;i<3;i++) res.a[i][i]=1;
       while(n){
        if(n&1) res=res*M;
        M=M*M;
        n>>=1;
    }
    return res;
}

ll a,b,c,d,p,n;
int num[maxn],x[maxn];


mat solve(int nn){
    A.a[0][0]=d;A.a[0][1]=c;A.a[0][2]=1;
    A.a[1][0]=1;A.a[2][2]=1;
    mat res=qpow(A,nn);
    return res*B;
}

int main(){
    int t;read(t);
    while(t--){
        read(a),read(b),read(c),read(d),read(p),read(n);
        if(n==1) writeln(a);
        else if(n==2) writeln(b);
        else{
            int tmp=1,sz=0;
            for(int i=1;i<=n&&tmp<=n;i++){
                num[++sz]=tmp;
                x[sz]=p/tmp;
                if(x[sz]==0) break;
                tmp=p/(p/tmp)+1;
            }

            num[++sz]=n+1;
            B=mat();
            B.a[0][0]=b;B.a[1][0]=a;
            for(int i=2;i<sz;i++){
                B.a[2][0]=x[i];
                B=solve(num[i+1]-max(3,num[i]));
            }
            writeln(B.a[0][0]);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hypHuangYanPing/article/details/81877920
今日推荐