zoukankan      html  css  js  c++  java
  • 快速幂

    一、整数快速幂

      题目描述

        给你三个整数 b,p,k 求 bp mod k;

      输入格式

        一行三个整数 b,p,k

      输出格式

        输出 bp mod k=s

      就是模板,打出来很简单,但有一个地方容易出错。

      看如下两个代码:

    #include <cstdio>
    #include <iostream>
    using namespace std;
    long long Mod=1000;
    long long Pow(long long a,long long b){
        long long ans=1;
        for(;b;b>>=1){
            if(b&1)ans*=a%Mod;
            a=(a*a)%Mod;
        }
        return ans;
    }
    int main(){
        long long n,m;
        scanf("%lld %lld %lld",&n,&m,&Mod);
        printf("%lld^%lld mod %lld=",n,m,Mod);
        printf("%lld
    ",Pow(n,m)%Mod);
        return 0;
    }
    #include <cstdio>
    #include <iostream>
    using namespace std;
    long long Mod=1000;
    long long Pow(long long a,long long b){
        long long ans=1;
        for(;b;b>>=1){
            if(b&1)ans=ans*a%Mod;
            a=(a*a)%Mod;
        }
        return ans;
    }
    int main(){
        long long n,m;
        scanf("%lld %lld %lld",&n,&m,&Mod);
        printf("%lld^%lld mod %lld=",n,m,Mod);
        printf("%lld
    ",Pow(n,m)%Mod);
        return 0;
    }

    显然第一个代码是错的,错在ans*=a%Mod这边,如果这么用的话,ans并没有取Mod,只对了a取Mod,这样会有什么后果呢?当ans过大的时候他就会溢出。(可能你们不会犯这样的错误但我就是智障的写成了第一个~~)

    整数快速幂的原理大家都很清楚就不说了,应用的话。。。是个人应该都知道怎么用吧。

    二、矩阵快速幂

      题目描述

        给定n×n的矩阵A,求Ak

      输入格式

        第一行两个整数n,k接下来n行每行n个数,表示Aij

      输出格式

        输出 矩阵Ak

        每个元素对109+7取mod

      说明/提示

         对于 100\%100% 的数据:1le n le 1001n1000 le k le 10^{12}0k1012
    |A_{i,j}| le 1000A
    i,j
    1000

     

        

    /*
    看了题面很简单,事实上他的确很简单
    
        如果你看明白了整数的快速幂,这个就很简单了,对k二进制分解,不断舍弃最低位直到k为0,如果它的最低位1就累加答案。
    
        记得×的时候单独开一个数组保存结果!!!!不然数组会不断累×。
    */
    #include <cstdio>
    #include<cstring>
    #define ll long long
    const int N=110,Mod=1e9+7;
    ll a[N][N],ans[N][N],n,k;//数据mod1e9为什么还要longlong?
    void Mul(){
        ll temp[N][N];
        memset(temp,0,sizeof(temp));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                for(int k=1;k<=n;k++)
                    temp[i][j]=(temp[i][j]+ans[i][k]*a[k][j]%Mod)%Mod;
        //如果没用long long乘法要强转long long不然比如1e9*1e9肯定会超int
        memcpy(ans,temp,sizeof(temp));
    }
    void Mulself(){
        ll temp[N][N];
        memset(temp,0,sizeof(temp));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                for(int k=1;k<=n;k++)
                    temp[i][j]=(temp[i][j]+a[i][k]*a[k][j]%Mod)%Mod;
        memcpy(a,temp,sizeof(temp));
    }
    int main(){
        scanf("%lld%lld",&n,&k);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                scanf("%lld",&a[i][j]);
                ans[i][j]=a[i][j];
            }
        k--;//ans初始值为一次方,所以要求的k次方只需乘k-1次方
        for(;k;k>>=1){
            if(k&1)Mul();
            Mulself();
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)
                printf("%lld ",ans[i][j]);
            printf("
    ");
        }
    }
    View Code

        

        

     
  • 相关阅读:
    [hdu5136]Yue Fei's Battle 2014 亚洲区域赛广州赛区J题(dp)
    Codeforces Round #280 (Div. 2)E Vanya and Field(简单题)
    [hdu5113]Black And White2014北京赛区现场赛B题(搜索加剪枝)
    BestCoder Round #20 部分题解(A,B,C)(hdu5123,5124,5125)
    2014年亚洲区域赛北京赛区现场赛A,D,H,I,K题解(hdu5112,5115,5119,5220,5122)
    UVA 11754 Code Feat (枚举,中国剩余定理)
    Codeforces Round #277.5 (Div. 2) A,B,C,D,E,F题解
    UVA 11426 GCD
    UVALive 4119 Always an integer (差分数列,模拟)
    UVA 10253 Series-Parallel Networks (树形dp)
  • 原文地址:https://www.cnblogs.com/anyixing-fly/p/12419641.html
Copyright © 2011-2022 走看看