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


    http://acm.hdu.edu.cn/showproblem.php?pid=5451

    题意:给定x  (0<x<2^{32})  求解 leftlfloor{y}=left(5+2sqrt6
ight)^{1+2^x}
ight
floor\%M

    思路: 由斐波那契数列的两种表示方法F[n]=left(frac{1+sqrt{5}}{2}
ight)^{n}-left(frac{1-sqrt{5}}{2}
ight)^{n}, 之后可以转化为 线性表示 F[n] = F[n-1] + F[n-2] ;

    同时可以看出 frac{1+sqrt{5}}{2}  和frac{1-sqrt{5}}{2} 是 一元二次方程x^2+x-1=0的两根, a  = 1, b = -1 又是之后递推式的系数;

    同理这里需要构造出两根为 5+2sqrt{6}5-2sqrt{6} ,这时 a = 1, b = –10 得 F[n] = 10F[n-1] – F[n-2]; (当然可以直接打表递推出关系式)

    如果不管指数,看成是一个 leftlfloor{y}=left(5+2sqrt{6}
ight)^{n}
ight
floor\%M  这道题将变成 hdu 2256 Problem of Precision

    之后需要知道如何对指数1+2^{x} 进行取模简化,问题是具体Mod 多少?

    套路是mod (M-1)*(M+1) ,具体证明详见:http://blog.csdn.net/acdreamers/article/details/25616461

    到这里指数取模之后,之后跑矩阵快速幂即可;

     

    细节: 前面矩阵快速幂原本只是跑指数-1次,正好把1抵消了;

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    #define rep0(i,l,r) for(int i = (l);i < (r);i++)
    #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
    #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
    #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
    #define MS0(a) memset(a,0,sizeof(a))
    #define MS1(a) memset(a,-1,sizeof(a))
    #define MSi(a) memset(a,0x3f,sizeof(a))
    #define pb push_back
    #define MK make_pair
    #define A first
    #define B second
    #define clear0 (0xFFFFFFFE)
    #define inf 0x3f3f3f3f
    #define eps 1e-8
    #define zero(x) (((x)>0?(x):-(x))<eps)
    #define bitnum(a) __builtin_popcount(a)
    #define lowbit(x) (x&(-x))
    #define K(x) ((x)*(x))
    typedef pair<int,int> PII;
    typedef long long ll;
    typedef unsigned int uint;
    typedef unsigned long long ull;
    template<typename T>
    void read1(T &m)
    {
        T x = 0,f = 1;char ch = getchar();
        while(ch <'0' || ch >'9'){ if(ch == '-') f = -1;ch=getchar(); }
        while(ch >= '0' && ch <= '9'){ x = x*10 + ch - '0';ch = getchar(); }
        m = x*f;
    }
    template<typename T>
    void read2(T &a,T &b){read1(a);read1(b);}
    template<typename T>
    void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
    template<typename T>
    void out(T a)
    {
        if(a>9) out(a/10);
        putchar(a%10+'0');
    }
    inline ll gcd(ll a,ll b){ return b == 0? a: gcd(b,a%b); }
    inline ll lcm(ll a,ll b){ return a/gcd(a,b)*b; }
    template<class T1, class T2> inline void gmax(T1& a, T2 b){ if(a < b) a = b;}
    template<class T1, class T2> inline void gmin(T1& a, T2 b){ if(a > b) a = b;}
    int mod;
    struct Matrix{
        int row, col;
        ll m[10][10];
        Matrix(int r,int c):row(r),col(c){ memset(m, 0, sizeof(m)); }
    
        bool unitMatrix(){
            if(row != col) return false;
            for(int i = 0;i < row;i++) //方阵才有单位矩阵;
                    m[i][i] = 1;
            return true;
        }
        Matrix operator *(const Matrix& t){
            Matrix res(row, t.col);
            for(int i = 0; i < row; i++)
                for(int j = 0;j < t.col;j++)
                    for(int k = 0; k < col; k++)
                        res.m[i][j] = (res.m[i][j] + m[i][k]*t.m[k][j])% mod;
            return res;
        }
        void print(){
            for(int i = 0;i < row; i++){
                for(int j = 0;j < col; j++)
                    printf("%lld ",m[i][j]);
                puts("");
            }
        }
    };
    
    Matrix pow(Matrix a, ll n)
    {
        Matrix res(a.row, a.col);
        res.unitMatrix();
        while(n){
            if(n & 1) res = res*a;
            a = a*a;
            n >>= 1;
        }
        return res;
    }
    ll POW(ll a,int n, ll mod)
    {
        ll ans = 1;
        while(n){
            if(n&1) ans = (ans*a)%mod;
            a = a*a%mod;
            n >>= 1;
        }
        return ans;
    }
    int main()
    {
        //freopen("data.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        Matrix mat(2,2);
        mat.m[0][0] = 5, mat.m[0][1] = 12;
        mat.m[1][0] = 2, mat.m[1][1] = 5;
        int T, kase = 1;
        scanf("%d",&T);
        while(T--){
            int n;
            read2(n, mod);
            ll MOD = 1LL*(mod-1)*(mod+1);
            MOD = POW(2,n,MOD);
            Matrix res = pow(mat, MOD);
            //res.print();
            Matrix tmp(2,1);
            tmp.m[0][0] = 5, tmp.m[1][0] = 2;
            res = res*tmp;
            printf("Case #%d: %d
    ",kase++, (2*res.m[0][0]-1)% mod);
        }
        return 0;
    }

    ps: 这道题循环节较小,直接求解循环节也可以A;

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    #define rep0(i,l,r) for(int i = (l);i < (r);i++)
    #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
    #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
    #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
    #define MS0(a) memset(a,0,sizeof(a))
    #define MS1(a) memset(a,-1,sizeof(a))
    #define MSi(a) memset(a,0x3f,sizeof(a))
    #define pb push_back
    #define MK make_pair
    #define A first
    #define B second
    #define clear0 (0xFFFFFFFE)
    #define inf 0x3f3f3f3f
    #define eps 1e-8
    #define zero(x) (((x)>0?(x):-(x))<eps)
    #define bitnum(a) __builtin_popcount(a)
    #define lowbit(x) (x&(-x))
    #define K(x) ((x)*(x))
    typedef pair<int,int> PII;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef unsigned int uint;
    template<typename T>
    void read1(T &m)
    {
        T x = 0,f = 1;char ch = getchar();
        while(ch <'0' || ch >'9'){ if(ch == '-') f = -1;ch=getchar(); }
        while(ch >= '0' && ch <= '9'){ x = x*10 + ch - '0';ch = getchar(); }
        m = x*f;
    }
    template<typename T>
    void read2(T &a,T &b){read1(a);read1(b);}
    template<typename T>
    void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
    template<typename T>
    void out(T a)
    {
        if(a>9) out(a/10);
        putchar(a%10+'0');
    }
    inline ll gcd(ll a,ll b){ return b == 0? a: gcd(b,a%b); }
    template<class T1, class T2> inline void gmax(T1& a, T2 b){ if(a < b) a = b;}
    template<class T1, class T2> inline void gmin(T1& a, T2 b){ if(a > b) a = b;}
    
    ll pow(ll a,uint n,int mod)
    {
        ll ans = 1;
        while(n){
            if(n&1) ans = (ans*a)%mod;
            a = a*a%mod;
            n >>= 1;
        }
        return ans;
    }
    const int maxn = 463370;
    int F[maxn];
    int main()
    {
        //freopen("data.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        int T, kase = 1;
        /*double d1 = 5+2*sqrt(6), d2 = 5 - 2*sqrt(6);
        rep1(i,1,10){
            printf("%.5f
    ",pow(d1,i)+pow(d2,i));
        }*/
        scanf("%d",&T);
        while(T--){
            uint x, mod;
            read2(x,mod);
            F[0] = 10%mod, F[1] = 98%mod;
            ll cycle = -1;
            for(int i = 2; ; i++){
                F[i] = (10*F[i-1] - F[i-2]+ mod)% mod;
                if(F[i] == F[1] && F[i-1] == F[0]){
                    cycle = i-1;
                    break;
                }
            }
            int p = pow(2,x, cycle);
            printf("Case #%d: %d
    ",kase++, F[p]-1);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    docker file和容器数据卷,发布镜像
    Docker的镜像原理和分层理解和打包镜像
    docker部署nginx,tomcat 练习
    Docker 命令和运行原理简单剖析
    Docker安装
    Java垃圾回收-栈和堆部分知识
    aio-pika的使用
    技术基础 | 在Apache Cassandra中改变VNodes数量的影响
    行业动态 | 通过使用Apache Cassandra实现实时供应链管理
    行业动态 | Apache Pulsar 对现代数据堆栈至关重要的四个原因
  • 原文地址:https://www.cnblogs.com/hxer/p/5724436.html
Copyright © 2020-2023  润新知