• 乘方快速幂 OR 乘法快速幂


          关于快速幂这个算法,已经不想多说,很早也就会了这个算法,但是原来一直靠着模板云里雾里的,最近重新学习,发现忽视了一个重要的问题,就是若取模的数大于int型,即若为__int64的时候应该怎么办,这样就得用到乘法快速幂+乘方快速幂了。

         快速幂一般是为了解决乘方取模问题的,显然思想就是二分,下面贴上快速幂模板:

     1 __int64 mulpow(__int64 a,__int64 p,__int64 m)
     2 {
     3     __int64 ans = 1;
     4     while(p)
     5     {
     6         if(p&1)
     7             ans = ans * a % m;
     8         p >>= 1;
     9         a = a * a % m;
    10     }
    11     return ans;
    12 }
    View Code

    但是以上代码有个问题,并不适合m超过int的情况,下面提供m超过int情况的解法

     1 __int64 multi(__int64 a,__int64 b,__int64 n)  //乘法快速幂
     2 {
     3     __int64 temp=0;
     4     while(b)
     5     {
     6         if(b&1)
     7         {
     8             temp+=a;
     9             if(temp>=n)  temp-=n;
    10         }
    11         a<<=1;
    12         if(a>=n) a-=n;
    13         b>>=1;
    14     }
    15     return temp;
    16 }
    17 
    18 __int64 mulpow(__int64 a,__int64 m,__int64 n)  //乘方快速幂
    19 {
    20     __int64 temp=1;
    21     a%=n;
    22     while(m)
    23     {
    24         if(m&1)  temp=multi(temp,a,n);
    25         a=multi(a,a,n);
    26         m>>=1;
    27     }
    28     return temp;
    29 }
    View Code

    但缺点就是速度慢了点,logn*logn的,感谢南理工的《ACM算法训练教程》

    poj3761

    链接:http://poj.org/problem?id=3761

    排列组合题目,但是真不好想,看了别人的题解才做出来的,orz别人的思维,是自己太弱了

    题解:http://blog.csdn.net/cscj2010/article/details/7820906

    这题典型的用快速乘方幂+快速乘法幂会TLE的

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<cmath>
     6 #include<vector>
     7 #include<algorithm>
     8 using namespace std;
     9 const int maxn=1000001;
    10 __int64 a[maxn];
    11 const int mod=20100713;
    12 __int64 mulpow(__int64 a,__int64 n,__int64 m)
    13 {
    14     __int64 temp=1;
    15     while(n)
    16     {
    17         if(n&1) temp=temp*a%m;
    18         a=a*a%m;
    19         n>>=1;
    20     }
    21     return temp;
    22 }
    23 int main()
    24 {
    25     __int64 n,k,T;
    26     a[0]=1;
    27     for(int i=1;i<=maxn;i++)
    28        a[i]=a[i-1]*i%mod;
    29     scanf("%I64d",&T);
    30     while(T--)
    31     {
    32         scanf("%I64d%I64d",&n,&k);
    33         printf("%I64d
    ",(a[k]*((mulpow(k+1,n-k,mod))-mulpow(k,n-k,mod)+mod)%mod)%mod);
    34     }
    35     return 0;
    36 }
    View Code
  • 相关阅读:
    写文件
    CI使用数据库
    ajxa方法
    find---查找文件或目录
    diff---比较文件不同
    ifup&&ifdown --- 激活/关闭指定的网络接口。
    ifconfig---配置和显示Linux内核中网络接口
    ssh-agent && 及 ssh-add介绍
    host---域名查询
    tracepath---追踪并显示报文到达目的主机所经过的路由信息。
  • 原文地址:https://www.cnblogs.com/wolf940509/p/4780601.html
Copyright © 2020-2023  润新知