HDU6395 多校赛Sequence

传送门----http://acm.hdu.edu.cn/showproblem.php?pid=6395

HDU6395 多校赛Sequence_第1张图片

思路:由于有后半部分的下取整,可以联想到整除分块去做。再用矩阵快速幂优化递推即可。

Code:

//2
#include
#include
#include
#include
#define LL long long
using namespace std;
const LL mod = 1000000007;
LL a, b, c, d, p, n;
struct martix
{
    LL m[4][4];
    martix()
    {
        memset(m, 0, sizeof(m));
    }
    martix operator*(const martix b)const
    {
        LL i, j, k;
        martix ans;
        for(i = 1; i <= 3; i++)
            for(j = 1; j <= 3; j++)
            {
                ans.m[i][j] = 0;
                for(k = 1; k <= 3; k++)
                {
                    ans.m[i][j] += m[i][k] * b.m[k][j];
                    ans.m[i][j] %= mod;
                }
            }
        return ans;
    }
};
void Debug (martix a)
{
    for(int i = 1; i <= 3; i++)
    {
        for(int j = 1; j <= 3; j++)
            cout << a.m[i][j] << ' ';
        cout << endl;
    }
}
martix martix_pow(LL n,LL x)
{
    martix temp, res;
    temp.m[1][1] = d;
    temp.m[1][2] = c;
    temp.m[1][3] = x;
    temp.m[2][1] = 1;
    temp.m[3][3] = 1;
    res.m[1][1] = res.m[2][2] = res.m[3][3] = 1;
    while(n)
    {
        if(n & 1)
            res = res * temp;
        temp = temp * temp;
        n >>= 1;
    }
    return res;
}
int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%lld%lld%lld%lld%lld%lld", &a, &b, &c, &d, &p, &n);
        if(n == 1)
            printf("%lld\n", a);
        else if(n == 2)
            printf("%lld\n", b);
        else
        {
            martix A, B;
            LL l, r;
            A.m[1][1] = A.m[2][2] = A.m[3][3] = 1;
            for(l = 3; l <= n; ++l)
            {
                r = (l <= p) ? min(p / (p / l), n) : n;
                A = (martix_pow(r - l + 1,p/l))*A;
                l=r;
               // Debug(A);
            }
            printf("%lld\n",(A.m[1][1]*b%mod+A.m[1][2]*a%mod+A.m[1][3])%mod);
        }
    }
}

 

你可能感兴趣的:(数论)