Live2d Test Env

HDU - 6395:Sequence (分块+矩阵)

题面太丑了,就不复制了。

题意:F1=A; F2=B; Fn=D*Fn-1+C*Fn-2+P/i;求Fn。

思路:根据P/i的值划分区间,每个区间矩阵求。

带常数的矩阵:

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int Mod=1e9+7;
struct mat
{
    int mp[3][3];
    mat(){memset(mp,0,sizeof(mp)); }
    mat friend operator *(mat a,mat b)
    {
        mat res;
        rep(k,0,2) rep(i,0,2) rep(j,0,2)
         res.mp[i][j]=(res.mp[i][j]+((ll)a.mp[i][k]*b.mp[k][j]%Mod))%Mod;
        return res;
    }
    mat friend operator ^(mat a,int x)
    {
        mat res;
        rep(i,0,2) res.mp[i][i]=1;
        while(x){
          if(x&1) res=res*a; a=a*a; x>>=1;
        }return res;
    }
};

int main()
{
    int T,N,A,B,C,D,P,fcy;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d%d%d%d",&A,&B,&C,&D,&P,&N);
        if(N==1) {printf("%d",A); continue;}
        if(N==2) {printf("%d",B); continue;}
        for(int i=3,r;i<=N;i=r+1){
            int tmp=P/i;
            if(tmp==0) r=N;
            else r=min(P/(P/i),N);
            mat ans,base;
            ans.mp[0][0]=B;ans.mp[1][0]=A; ans.mp[2][0]=1;
            base.mp[0][0]=D; base.mp[0][1]=C; base.mp[0][2]=tmp;
            base.mp[1][0]=base.mp[2][2]=1;
            ans=(base^(r-i+1))*ans;
            if(r==N) fcy=ans.mp[0][0];
            else B=ans.mp[0][0],A=ans.mp[1][0];
        }
        printf("%d\n",fcy);
    }
    return 0;
}

 

posted @ 2018-10-22 09:42  nimphy  阅读(149)  评论(0编辑  收藏  举报