2 条题解

  • 7
    @ 2023-11-4 10:28:15

    快速幂

    /* 核心思想:分治
    a^b = a*a*...*a  //b个a相乘 
    	= (a*a)*(a*a)*...*(a*a)*(a*a)  //b为偶数,即 b%2==0  b/2个(a*a)相乘 
    	= [(a*a)*(a*a)]*...[(a*a)*(a*a)]  //逐级合并 a   b/2/2个[(a*a)*(a*a)]相乘
    	【或= (a*a)*(a*a)*...*a  //b为奇数,即 b%2==1  (b/2)的整数部分个(a*a)相乘
    		= [(a*a)*(a*a)]*...[(a*a)*(a*a)]*a  //逐级合并 a  】
    
    eg. b=2, p=5, k=3
    b^p = 2^5  //b = 2
    	= 2*2*2*2*2  //p(=5)%2==1,a = a*b = 1*2 = 2,p/2 = 5/2 = 2
    	= (2*2)*(2*2)*2  //b = b*b = 2*2 = 4
    	= 4*4*2  //p(=2)%2==0,a = 2,p/2 = 2/2 = 1
    	= (4*4)*2  //b = b*b = 4*4 = 16
    	= 16*2  //p(=1)%2==1,a = a*b = 2*16 = 32,p/2 = 1/2 = 0 【循环结束】 
    	= 32
    */
    
    #include<cstdio>
    using namespace std;
    
    int main(){
        long long a=1, b, p, k;
        scanf("%lld%lld%lld", &b, &p, &k);
         
        /* 补充一个定理:a*b%p = (a%p)*(b%p)%p
        由此定理,为了防止 long long 溢出,每一次 *b 后可以执行 %k 操作 
    	*/ 
        while(p){
        	if(p%2) a = a*b%k; 
            b = b*b%k; 
            p /= 2;
        }
        
        printf("%lld\n", a%k);
    
        return 0;
    }
    
    • 3
      @ 2022-11-25 10:55:07
      #include<bits/stdc++.h>
      using namespace std;
      long long b,a,p,k,ans=1,c;
      int main()
      {
      scanf("%lld%lld%lld",&b,&p,&k);
      a=b;c=p;
      while(p>0)//快速幂
      {
      if(p%2!=0)
      ans=ans*b%k;//如果p为单数,乘到ans里面去,然后取模
      b=b*b%k;//每次运算都取模
      p/=2;    //分治,分而治之
      }
      ans %= k;
      printf("%lld",ans);//输出
      return 0;
      }
      
      • 1

      信息

      ID
      431
      时间
      1000ms
      内存
      256MiB
      难度
      7
      标签
      递交数
      111
      已通过
      27
      上传者