BISHI75 阶幂

如果 ab≥ma^b \ge mab≥m,返回 (ab mod m)+m(a^b \bmod m) + m(abmodm)+m;否则直接返回 aba^bab。

思路

代码实现

java 复制代码
 private static long MOD = 1000000007;  // 定义模数常量,用于取模运算
    private static List<Long> mList = new ArrayList<>();  // 存储欧拉函数值的列表

    /**
     * 主方法,处理输入输出并计算结果
     *
     * @param args 命令行参数
     * @throws IOException 可能抛出IO异常
     */
    public static void main(String[] args) throws IOException {
        // 使用BufferedReader读取输入,PrintWriter输出结果
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

        // 读取输入的长整型数值n
        long n = Long.parseLong(br.readLine().trim());

        // 初始化tmp为MOD值,并添加到mList列表中
        long tmp = MOD;
        mList.add(tmp);

        // 计算欧拉函数值直到tmp为1,并将结果添加到mList中
        while (tmp > 1) {
            tmp = getPhi(tmp);
            mList.add(tmp);
        }

        // 调用solve方法计算结果并输出,取模MOD
        out.println(solve(n, 0) % MOD);


        // 清空输出缓冲区并关闭资源
        out.flush();
        out.close();
        br.close();
    }

    /**
     * 递归求解模幂运算的结果
     *
     * @param curN 当前处理的数字
     * @param idx  当前处理的mList中的索引位置
     * @return 返回模幂运算的结果
     */
    private static long solve(long curN, int idx) {
        // 获取当前索引对应的模数
        long m = mList.get(idx);
        // 如果模数为1,任何数对1取模结果都是1
        if (m == 1) {
            return 1;
        }

        // 如果当前数字为1,1的任何次幂都是1
        if (curN == 1) {
            return 1;
        }

        // 递归计算指数部分,curN-1和idx+1表示递归处理下一个数字和下一个模数
        long exp = solve(curN - 1, idx + 1);

        // 计算curN的exp次幂对m取模的结果
        return safePow(curN, exp, m);
    }

    /**
     * 安全的幂运算函数,计算 a^b mod m,并处理可能的溢出情况
     *
     * @param a 底数
     * @param b 指数
     * @param m 模数
     * @return 计算结果,如果发生溢出则返回结果加上模数后的值
     */
    private static long safePow(long a, long b, long m) {
        long res = 1;        // 初始化结果为1
        boolean overflow = false;  // 溢出标志,初始为false

        // 如果底数大于等于模数,进行取模操作,并标记可能溢出
        if (a >= m) {
            overflow = true;
            a %= m;
        }

        // 使用快速幂算法计算幂运算
        while (b > 0) {
            // 如果当前指数的二进制最低位为1(即指数为奇数)
            if ((b & 1) == 1) {
                res = res * a;   // 将当前底数乘入结果
                // 如果结果大于等于模数,进行取模操作,并标记可能溢出
                if (res >= m) {
                    overflow = true;
                    res %= m;
                }
            }

            b >>= 1;   // 指数右移一位,相当于除以2
            // 如果指数还有剩余位
            if (b > 0) {
                a = a * a;   // 底数平方
                // 如果平方后的底数大于等于模数,进行取模操作,并标记可能溢出
                if (a >= m) {
                    overflow = true;
                    a %= m;
                }
            }
        }
        // 根据溢出标志返回结果,如果溢出则加上模数
        return overflow ? (res + m) : res;
    }

    /**
     * 计算欧拉函数Phi(n)的值
     * 欧拉函数Phi(n)表示小于n的正整数中与n互质的数的个数
     *
     * @param n 需要计算欧拉函数的正整数
     * @return 返回n的欧拉函数值
     */
    private static long getPhi(long n) {
        long res = n;  // 初始化结果为n

        // 遍历2到sqrt(n)的所有整数
        for (long i = 2; i * i <= n; i++) {
            // 如果i是n的因数
            if (n % i == 0) {
                // 应用欧拉函数的公式:res = res * (1 - 1/p)
                res = res / i * (i - 1);
                // 去除n中所有的i因子
                while (n % i == 0) {
                    n /= i;
                }
            }
        }

        // 如果n大于1,说明n本身是一个质数
        if (n > 1) {
            res = res / n * (n - 1);
        }
        return res;
    }
相关推荐
冉冰学姐1 天前
基于ssm的技能比赛报名管理系统29817vn0(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
java·数据库·spring·ssm 框架应用
代码雕刻家1 天前
3.5.Maven-依赖管理-依赖配置&依赖传递
java·maven
Cg136269159741 天前
JS-对象-Dom案例
开发语言·前端·javascript
!chen1 天前
MyBatis-plus拓展之字段类型处理器、自动填充和乐观锁
java·tomcat·mybatis
故事和你911 天前
sdut-程序设计基础Ⅰ-实验五一维数组(8-13)
开发语言·数据结构·c++·算法·蓝桥杯·图论·类和对象
Jin、yz1 天前
JAVA 八股
java·开发语言
va学弟1 天前
Java 网络通信编程(6):视频通话
java·服务器·网络·音视频
我是唐青枫1 天前
C#.NET Span 深入解析:零拷贝内存切片与高性能实战
开发语言·c#·.net
pjw198809031 天前
Spring Framework 中文官方文档
java·后端·spring
lxh01131 天前
数据流的中位数
开发语言·前端·javascript