KY16 求root(N,k)求数根 数根

本文介绍了如何利用数根理论和模运算技巧解决大整数快速幂问题,通过先取模再进行幂次计算,避免整数溢出。关键在于理解数根的意义和快速幂的模运算规则。
摘要由CSDN通过智能技术生成

题目:

  • 本题一开始不太有思路,参照了各个题解和分析,学到了一些东西,记录一下。

描述

N<k时,root(N,k) = N,否则,root(N,k) = root(N',k)。
N'为N的k进制表示的各位数字之和。
输入x,y,k,输出root(x^y,k)的值
 (这里^为乘方,不是异或),
2=<k<=16,0<x,y<2000000000,
有一半的测试点里 x^y 会溢出int的范围(>=2000000000) 

输入描述:

每组测试数据包括一行,x(0<x<2000000000), y(0<y<2000000000), k(2<=k<=16)

输出描述:

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

示例1:

|输入: 4 4 10
|输出: 4

需要补充的数学理论知识

  1. 数根: 整数的各个数位数字之和具有什么意义?相等意味着什么
  2. 模的运算法则
  3. 快速幂
    有了上述的理解基础,那么这道题就有了理解的基础

关键

    1. 首先本题幂次较高,很容易超出int 表示范围,求快速幂的时候最好用 long long;
    1. 但实际上,在求快速幂的过程中,利用模的运算法则,和数根的理论,一边求幂一边取模,进而减小参与运算的数值大小,减小溢出的可能性,适合于这道题解法。
    1. 即由(xy)%p=(x%py%p)%p,((ab)%pc)%p=(a(ba)%p)%p;
  • 那么(xx)%p=(x%px%p)%p;
  • 所以在求幂次之前,先取模再乘上幂次取模结果不影响。
#include <iostream>
using namespace std;

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

int fastExp(int x, int y, int k) {
    int answer = 1;
    while (y != 0) {
        if (y % 2 != 0) {
            answer *= x;
            answer %= (k - 1);\\直接先求模,减小数值范围
        }
        x %= (k - 1);\\先求模减小数值范围
        x *= x;
        // 注意,如果先乘再取模要用long long
        // 要不然x*x会超过int范围
        y >>= 1;
    }
    return answer;
}

int main() {
    int x, y, k;
    cin >> x >> y >> k;
    int m = fastExp(x, y, k);
    \\注意 这个快速幂里保证了每一步都求模,即保证了对原数k进制转换。
    if (m == 0) {\\对取模为0的处理,实际上余数为k-1;
        m += k - 1;
    }
    cout << m;
}

参考的题解与博客:

【数论】数根,求root(N,k)

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值