hdu 5451 Best Solver

很显然这是矩阵快速幂的题

但发现用矩阵快速幂,指数很大很大,没办法用欧拉降幂(傻乎乎的用欧拉降幂,欧拉降幂只是对底数为整数,做了3个小时),结果是由周期的,根据周期对指数进行降幂,然后再矩阵快速幂,最后答案减一,因为这是求的向上取整

AC code:

#include <bits/stdc++.h>

using namespace std;
const int N = 1e6 + 10;
const int M = 2;

typedef long long ll;

int m=2;
int MOD;
struct Matrix{
    ll matrix[M][M];
};
void init(Matrix &res)
{
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<m;j++)
            res.matrix[i][j]=0;
        res.matrix[i][i]=1;
    }
}
Matrix multiplicative(Matrix a,Matrix b)
{
    Matrix res;
    memset(res.matrix,0,sizeof(res.matrix));
    for(int i = 0 ; i <m; i++)
        for(int j = 0 ; j < m ; j++)
            for(int k = 0 ; k < m; k++)
                res.matrix[i][j] = (res.matrix[i][j]+a.matrix[i][k]%MOD*b.matrix[k][j]%MOD+MOD)%MOD;
    return res;
}
Matrix pow(Matrix mx,ll m)
{
    Matrix res,base=mx;
    init(res); //初始为单位矩阵,即除主对角线都是1外,其他都是0
    while(m)
    {
        if(m&1)
            res=multiplicative(res,base);
        base=multiplicative(base,base);
        m>>=1;
    }
    return res;
}

ll fast_pow(ll a,ll n,ll mod)
{
    ll ans = 1;
    while(n)
    {
        if(n&1) ans = ans * a % mod;
        a = a*a % mod;
        n >>= 1;
    }
    return ans;
}
ll ans[N];

int looped[46337 + 10];

int getloop(int mod)
{
    if(looped[mod]) return looped[mod];
    ans[0] = 2%mod;ans[1] = 10%mod;
    for(int i = 2;;i++)
    {
        ans[i] = (ans[i - 1]*10ll%mod - ans[i - 2] + mod)%mod;
     //   cout<<i<<endl;
        if(ans[i-1] == ans[0] && ans[i] == ans[1])    return looped[mod] = i - 1;

    }

}

int main()
{
    int t,kase = 0,x;
    memset(looped,0,sizeof(looped));
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&x,&MOD);
        int loop = getloop(MOD);
        //cout<<loop<<endl;
        int n = (fast_pow(2,x,loop) + 1 ) % loop;
        ll a = 5;
        ll b = 24;
        //cout<<n<<endl;
        if(n == 0)  printf("Case #%d: %lld\n",++kase,1%MOD);
        else if(n == 1)  printf("Case #%d: %lld\n",++kase,(2*a-1)%MOD);
        else{
            Matrix base={
                2*a,-(a*a-b),
                1,0
            };
            base=pow(base,n-1);
            printf("Case #%d: %lld\n",++kase,(2*a%MOD*base.matrix[0][0]%MOD+2*base.matrix[0][1]%MOD+MOD - 1)%MOD);
        }
    }
}

原文地址:https://www.cnblogs.com/lemon-jade/p/9736345.html

时间: 2024-11-08 20:36:40

hdu 5451 Best Solver的相关文章

Hdu 5451 Best Solver (2015 ACM/ICPC Asia Regional Shenyang Online) 暴力找循环节 + 递推

题目链接: Hdu  5451  Best Solver 题目描述: 对于,给出x和mod,求y向下取整后取余mod的值为多少? 解题思路: x的取值为[1, 232],看到这个指数,我的心情是异常崩溃的.(吐血......) 可是仔细观察,它指数大,可是mod小啊,它吓人,可是可以暴力搞啊!! 这个题目一个难点就是要向下取整求余,详解见传送门,本题是向下取整,也就是向上取整加一. 还有就是指数太大,要找到循环节,其实由于mod小,循环节并没有太大,暴力跑就ok啦!  此刻内心是崩溃的 1 #i

hdu 5451 Best Solver 矩阵循环群+矩阵快速幂

http://acm.hdu.edu.cn/showproblem.php?pid=5451 题意:给定x    求解 思路: 由斐波那契数列的两种表示方法, 之后可以转化为 线性表示 F[n] = F[n-1] + F[n-2] ; 同时可以看出   和 是 一元二次方程的两根, a  = 1, b = -1 又是之后递推式的系数: 同理这里需要构造出两根为 和 ,这时 a = 1, b = –10 得 F[n] = 10F[n-1] – F[n-2]; (当然可以直接打表递推出关系式) 如果

ACM学习历程—HDU 5451 Best Solver(Fibonacci数列 &amp;&amp; 快速幂)(2015长春网赛1007题)

Problem Description The so-called best problem solver can easily solve this problem, with his/her childhood sweetheart. It is known that y=(5+2√6)^(1+2^x).For a given integer x (0≤x<2^32) and a given prime number M (M≤46337) , print [y]%M . ([y] mean

特征根法求通项+广义Fibonacci数列找循环节 - HDU 5451 Best Solver

Best Solver Problem's Link Mean: 给出x和M,求:(5+2√6)^(1+2x)的值.x<2^32,M<=46337. analyse: 这题需要用到高中的数学知识点:特征根法求递推数列通项公式. 方法是这样的: 对于这题的解法: 记λ1=5+2√6,λ2=5-2√6,则λ1λ2=1,λ1+λ2=10 根据韦达定理可以推导出:λ1,λ2的特征方程为 x^2-10x+1=0 再使用该特征方程反向推导出递推公式为:a[n]=10*a[n-1]-a[n-2] 再由特征根

hdu 5451 Best Solver(矩阵快速幂+循环节)

题意: 已知,给你整数x,和一个素数M,求[y]%M 思路: 设 (5+2√6)n=Xn+Yn*√6 Xn+Yn*√6 =(Xn-1+Yn-1*√6)*(5+2√6) => 5*Xn-1 + 12*Yn-1 + (2*Xn-1 + 5*Yn-1 )*√6 Xn =  5*Xn-1 + 12*Yn-1: Yn =  2*Xn-1 + 5*Yn-1: 然而√6还是一个大问题,解决办法: (5 - 2√6)n = Xn - Yn*√6 (5+2√6)n=Xn+Yn*√6 + Xn - Yn*√6 -

HDU 5451 Best Solver(fibonacci)

感谢这道题让我复习了一遍线代,还学习了一些奇奇怪怪的数论. 令 二项展开以后根号部分抵消了 显然有 所以要求的答案是 如果n比较小的话,可以直接对二项式快速幂,但是这题n很大 这个问题和矩阵的特征值以及数列递推有奇怪的联系 广义的fibonacci数列的形式如下 写成矩阵形式就是 有一个奇怪的结论: 其中lambda1,lambda2是递推矩阵的特征值,此处只讨论lambda1!=lambda2的情况. 这个奇怪的结论其实很容易证明, 根据以上结果,利用矩阵的数乘和分配律然后归纳就可以完整得到结

【矩阵快速幂+循环节】HDU 5451 Best Solver

通道 题意:计算(5+26√)1+2^x. 思路:循环节是(p+1)*(p-1),然后就是裸的矩阵快速幂啦. 代码: #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N = 2; int MOD; struct

HDU 5451 广义斐波那契数列

这道题目可以先转化: 令f(1) = 5+2√6 f(2) = f(1)*(5+2√6) ... f(n) = f(n-1)*(5+2√6) f(n) = f(n-1)*(10-(5-2√6)) = 10*f(n-1)-(5-2√6)f(n-1) = 10*f(n-1) - 10/(5+2√6) f(n-1) = 10*f(n-1) - 10/(5+2√6) * (5+2√6)f(n-2) = 10*f(n-1) - f(n-2) 那么就可以写成矩阵相乘的形式了 (f(n) , f(n-1))

HDU 5451

题目要求:y = (5 + 2√6)1+2^x 设An=(5 + 2√6)n,Bn=(5 - 2√6)n Cn = An + Bn 显然Cn是正整数,且Bn是小于1的 所以我们所求的答案其实就是Cn - 1 通过推导: Cn * [(5 + 2√6) + (5 - 2√6)] = ((5 + 2√6)n + (5 - 2√6)n) * [(5 + 2√6) + (5 - 2√6)] = (5 + 2√6)n + 1 + (5 - 2√6)n + 1) + (5 + 2√6)n - 1 + (5