zoukankan      html  css  js  c++  java
  • hdu 5895(矩阵快速幂+欧拉函数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5895

    f(n)=f(n-2)+2*f(n-1)
    f(n)*f(n-1)=f(n-2)*f(n-1)+2*f(n-1)*f(n-1);
    2*f(n-1)*f(n-1)=f(n)*f(n-1)-f(n-2)*f(n-1);
    累加可得 g(n) = f(n)*f(n+1)/2
     
    然后这个公式:A^x % m = A^(x%phi(m)+phi(m)) % m (x >= phi(m))
     
    反正比赛没做出来.
    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    struct Maxtri{
        LL v[2][2];
        Maxtri(){memset(v,0,sizeof(v));}
    }ori;
    LL n, y, x, s, mod ;
    Maxtri mult(Maxtri a,Maxtri b){
        Maxtri temp;
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                for(int k=0;k<2;k++){
                    temp.v[i][j] = (temp.v[i][j]+(a.v[i][k]*b.v[k][j])%mod)%mod;
                }
            }
        }
        return temp;
    }
    LL pow_mod(Maxtri a,LL n){
        if(n==0) return 0;
        if(n==1) return 1;
        if(n==2) return 2;
        n-=2;
        Maxtri ans;
        for(int i=0;i<2;i++){
            ans.v[i][i] = 1;
        }
        while(n){
            if(n&1) ans = mult(ans,a);
            a = mult(a,a);
            n>>=1;
        }
        return (ans.v[0][0]*2+ans.v[0][1])%mod;
    }
    LL pow_mod1(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 Phi(LL x)
    {
        LL ans = x;
        for(LL i=2LL; i*i<=x; i++)
        {
            if(x % i == 0)
            {
                ans -= ans/i;
                while(x % i == 0)
                    x /= i;
            }
        }
        if(x > 1)
            ans -= ans/x;
        return ans;
    }
    int main(){
        ori.v[0][0] = 2,ori.v[0][1] = 1;
        ori.v[1][0] = 1,ori.v[1][1] = 0;
        int tcase;
        scanf("%d",&tcase);
        while(tcase--){
            scanf("%lld%lld%lld%lld",&n, &y, &x, &s);
            s++;
            LL phi = 2*Phi(s);
            mod = 2*phi;
            LL fn = pow_mod(ori,n*y);
            LL fn1 = pow_mod(ori,n*y+1);
            LL ans = ((fn*fn1)%mod/2);
            ans+=phi;
            printf("%lld
    ",pow_mod1(x,ans,s)%s);
        }
        return 0;
    }
  • 相关阅读:
    JDK API文档下载
    idea技巧:查看一个类的所有子类以及子类的子类并以层级关系显示
    Vue项目优化
    deepin 安装netcore 记录
    UOS 下的VScode 使用经验
    UOS操作系统磁盘空间不够一例
    SRPBatcher优化的原理
    我的UOS生活
    假如美国禁用了Unity3D和Unreal怎么办
    BGFX学习笔记01
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5911128.html
Copyright © 2011-2022 走看看