求root(N, k) 快速幂取模的应用

原文地址:https://blog.qjm253.cn/?p=371

问题描述

N=2000000000)

输入描述

每组测试数据包括一行,x(0

输出描述

输入可能有多组数据,对于每一组数据,root(x^y, k)的值

示例

  • 输入
    4 4 10
    
  • 输出
    4
    

分析推导

  1. 首先将 N用k进制表示 展开:

N = a0 + a1 * k + a2 * k2 + ··· + a0 * kn

  1. 则,N' 表示如下:

N' = a0 + a1 + a2 + ··· + an

  1. N - N' 表示如下:

N - N' = a1 * (k - 1) + a2 * (k2 - 1) + ··· + an * (kn - 1)

  1. 证明 (N - N') % (k - 1) = 0

由等比数列求和公式有: 1 + k + k2 + ··· + kn - 1 = (1 - kn) / (1 - k)

kn - 1 = (k - 1) * (1 + k + k2 + ··· + kn - 1)

(kn - 1) % (k - 1) = 0

又∵ N - N' = a1 * (k - 1) + a2 * (k2 - 1) + ··· + an * (kn - 1)

(N - N') % (k - 1) = 0

  1. 递推归纳

令 N' = N1, N" = N2, ···

则有:

    (N - N1) % (k - 1) = 0

    (N1 - N2) % (k - 1) = 0

    ...

    (Nr - 1 - Nr) % (k - 1) = 0

    其中 Nr 为我们要求的结果

将上面的各个递推公式相加得到:

    (N - Nr) % (k - 1) = 0

Nr = N % (k - 1)

  1. 得出结论

root(N, k) = N % (k - 1)

快速幂取模算法

点我查看

算法实现

此算法实现基于上面数学推得到的结论,以及快速幂取模算法

#include 

using namespace std;

long root(long x, long y, int k){
    long ans = 1;
    k -= 1;
    x %= k;
    while(y != 0){
        if(y & 1)
           ans = (ans * x) % k;
        y >>= 1;
        x = (x * x) %k;
    }
    return ans == 0 ? k : ans;
}

int main(){
    long x, y;
    int k;

    while(cin >> x >> y >> k)
        cout << root(x, y, k);
}

你可能感兴趣的:(求root(N, k) 快速幂取模的应用)