zoukankan      html  css  js  c++  java
  • 杭电多校第七场-J-Sequence

    题目描述

    Let us define a sequence as below

    Your job is simple, for each task, you should output Fn module 109+7.

    输入

    The first line has only one integer T, indicates the number of tasks.
    Then, for the next T lines, each line consists of 6 integers, A , B, C, D, P, n.
    1≤T≤20  0≤A,B,C,D≤109  1≤P,n≤109

    输出

    output Fn module 109+7.

    样例输入

    2
    3 3 2 1 3 5
    3 2 2 2 1 4

    样例输出

    36
    24

     

    矩阵快速幂
    问题在于p/i
    上图为p=100的表,可以发现p/i相同的连续的一段的最后一个数的坐标为p/(p/i) ,然后分段做就可以了
    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int p=1e9+7;
    int n,P,T;
    ll a,b,c,d;
    struct Mat
    {
        ll v[3][3];
    
        Mat() {
            memset(v, 0, sizeof(v));
        }
        void init()
        {
            for (int i=0;i<3;i++)
                v[i][i]=(ll)1;
        }
    
    };
    Mat operator *(Mat a,Mat b)
    {
        Mat c;
        for (int i=0;i<3;i++)
        {
            for (int j=0;j<3;j++)
            {
                c.v[i][j]=0;
                for (int k=0;k<3;k++)
                c.v[i][j]+=((a.v[i][k]%p*b.v[k][j]%p)%p+p)%p;
            }
        }
        return c;
    }
    Mat qmod(Mat a,int k)
    {
        Mat c;
        c.init();
    
        while (k)
        {
            if (k&1) c=c*a;
            a=a*a;
            k>>=1;
        }
        return c;
    }
    void solve()
    {
        scanf("%lld%lld%lld%lld%d%d",&a,&b,&c,&d,&P,&n);
        Mat mp;
        mp.v[0][0]=d; mp.v[0][1]=c;
        mp.v[1][0]=1; mp.v[2][2]=1;
    
        for (int i=3;i<=n;)
        {
    
            if(P/i==0)
            {
                Mat w=mp;
                w=qmod(w,n-i+1);
                cout<<(w.v[0][0]*b+w.v[0][1]*a+w.v[0][2])%p<<endl;
                return;
            }
    
            int j=min(n,P/(P/i));
            Mat w=mp;
            w.v[0][2]=P/i;
            w=qmod(w,j-i+1);
            ll ans_a=(w.v[1][0]*b+w.v[1][1]*a+w.v[1][2])%p;
            ll ans_b=(w.v[0][0]*b+w.v[0][1]*a+w.v[0][2])%p;
            a=ans_a;b=ans_b;
            i=j+1;
    
        }
        printf("%lld
    ",b);
    }
    int main()
    {
        scanf("%d",&T);
        while (T--) solve();
        return 0;
    }
    View Code
  • 相关阅读:
    SQL执行效率1
    php经典算法(转载)
    linux自用命令
    vim基本命令
    xampp安装
    BUU-rsa
    z3约束器学习笔记
    面试前夕oi挣扎式复习
    bss上的格式化字符串漏洞
    一、汇编
  • 原文地址:https://www.cnblogs.com/tetew/p/9501747.html
Copyright © 2011-2022 走看看