• 数的阶乘幂 && 洛谷 U132839 幂(数学,快速幂)


    传送门


    解题思路

    先看一下数据范围,a、b、c都是10^6,所以大体推断出做法时间复杂度约为nlogn。

    根据axy=(ax)^y,所以ab!=(((((a^1)^2)^3)^4)^……)^b。

    用底数变化的快速幂(O(logb))做b次即可。

    或者对指数b!做一些处理——

    我们知道指数b!一定不能直接mod,但是我们把b! mod一个x,使得结果不变。

    其中x要保证axmod c=1。很显然,这样做就等于把b!-kx,等于ab!/akx,结果不变。

    怎么保证一定有这个x呢?

    我们把a1,a2,a3……ac  %c写出来

    • 当存在一个x使得ax%c=0时,只需判断b!是否大于等于x,若大于等于,结果为0,否则结果直接快速幂算即可。
    • 若不存在x使得ax%c=0,那么我们不妨设不存在ax%c=1,即ak%c ε [2,c-1](k:1~c)。那么一定存在两个数s和t(s>t),as%c=at%c。那么很显然,as-t%c=1。这与假设相违背,所以一定存在这个x。

    所以这两种做法都可以过此题,第一种O(nlogn),第二种O(n)。

    另外看60分做法,模数是质数,我们可以想到费马小定理——ap-1%p=1,这时,c-1即是我们要找的x。

    AC代码(第一种做法)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 using namespace std;
     6 long long a,b,c;
     7 long long kuaisumi(long long a,int x){
     8     if(x==1) return a%c;
     9     long long ans;
    10     if(x&1) ans=a%c;
    11     else ans=1;
    12     long long kkk=kuaisumi(a,x/2);
    13     ans=ans*kkk%c*kkk%c;
    14     return ans;
    15 }
    16 long long work(long long a,long long b){
    17     while(b>0){
    18         a=kuaisumi(a,b);
    19         b--;
    20     }
    21     return a%c;
    22 }
    23 int main(){
    24     cin>>a>>b>>c;
    25     cout<<work(a,b)%c<<endl;
    26     return 0;
    27 }
  • 相关阅读:
    c#对XML读取
    WPF--TypeConverter使用
    WPF---对于没有Command属性的添加以下代码可以达到有Command效果
    自定义事件、属性、方法
    读取Excel文件
    ClickOnce安装部署,手动。
    Logger 日志记录
    Maven
    等待与通知范式
    线程状态及基本方法
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/13758000.html
Copyright © 2020-2023  润新知