HDU 多校 6395 Sequence(分段矩阵快速幂

解析:
初始矩阵(B,A,1)
单位矩阵(1,1,0,2,0,0,K,0,1) 其中K可以分成好几段,分段具体看代码

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define pb push_back
#define mod 1000000007
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rep1(i,b,a) for(int i=b;i>=a;i--)
using namespace std;
const int N=1e5+100;
ll c,t,A,B,C,D,P,k;
struct node
{
    ll m,l;
    ll v[3][3];
};
node a;
node get_mul(node aa,node bb)
{
    node c;
    c.m=aa.m,c.l=bb.l;
    for(int i=0;i<c.m;i++)
    {
        for(int j=0;j<c.l;j++)
        {
            c.v[i][j]=0;
            for(int k=0;k<aa.l;k++)
            {
                c.v[i][j]=(c.v[i][j]+(aa.v[i][k]*bb.v[k][j])%mod)%mod;
            }
        }
    }
    return c;
}
void getresult(ll n,node b)
{
    while(n)
    {
        if(n&1)
            a=get_mul(a,b);
        b=get_mul(b,b);
        n>>=1;
    }
}
int main()
{
    //freopen("D://r.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        node b;
        cin>>A>>B>>C>>D>>P>>c;
        ll arr[3][3]=
        {
             D,1,0,
             C,0,0,
             P/3,0,1
        };
        b.l=3,b.m=3;
        rep(i,0,3)
            rep(j,0,3)
                b.v[i][j]=arr[i][j];
        a.l=3,a.m=1;
        a.v[0][0]=B,a.v[0][1]=A,a.v[0][2]=1;
        if(c==1) {cout<<A<<endl;continue;}
        if(c==2) {cout<<B<<endl;continue;}
        ll mi=3,x=P/3,mx;
        if(x!=0)mx=P/x;
        else mx=c;
        while(1)
        {
            b.v[2][0]=x;
            mx=min(mx,c);
            ll len=mx-mi+1;
            getresult(len,b);
            if(mx==c)
            {
                cout<<a.v[0][0]<<endl;
                break;
            }
            mi=mx+1;
            x=P/(mi);
            if(x==0)
            {
                mx=c;
                continue;
            }
            mx=P/x;
        }
    }
    return 0;
}

posted @ 2018-08-13 19:23  ffgcc  阅读(108)  评论(0编辑  收藏  举报