《算法竞赛进阶指南》0x01 位运算-2.增加模数

AcWing 5579. 增加模数

题目描述

给定 H H H 对非负整数数对 ( A i , B i ) (A_i,B_i) (Ai,Bi) 和一个正整数 M M M。

请你计算并输出 ( A 1 B 1 + A 2 B 2 + ... + A H B H )   m o d   M (A_1^{B_1}+A_2^{B_2}+...+A_H^{B_H}) \bmod M (A1B1+A2B2+...+AHBH)modM。

输入格式

第一行包含整数 T T T,表示共有 T T T 组测试数据。

每组数据第一行包含整数 M M M。

第二行包含整数 H H H。

接下来 H H H 行,每行包含两个整数 A i , B i A_i,B_i Ai,Bi。

输出格式

每组数据输出一行结果。

数据范围

1 ≤ T ≤ 100 1 \le T \le 100 1≤T≤100,
1 ≤ M ≤ 45000 1 \le M \le 45000 1≤M≤45000,
1 ≤ H ≤ 45000 1 \le H \le 45000 1≤H≤45000,
0 ≤ A i , B i ≤ 10 7 0 \le A_i,B_i \le 10^7 0≤Ai,Bi≤107,
A i A_i Ai 和 B i B_i Bi 不同时为 0 0 0。

输入样例:
复制代码
3
16
4
2 3
3 4
4 5
5 6
36123
1
2374859 3029382
17
1
3 18132
输出样例:
复制代码
2
13195
13
解题思路

可参考《算法竞赛进阶指南》0x01 位运算-1.a^b

参考代码
无注释
cpp 复制代码
#include<bits/stdc++.h>
#define ll long long

using namespace std;
ll kusumi(ll a, ll b, ll mod){
    ll ans =1;
    while(b){
        if(b & 1)
            ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}

int main(){
    ios::sync_with_stdio(false), cin.tie(0);
    int t;
    cin >> t;
    while(t--){
        int m, h;
        cin >> m >> h;
        ll ans = 0;
        while(h --){
            int a, b;
            cin >> a >> b;
            ans += kusumi(a, b, m);
            ans %= m;
        }
        cout << ans <<"\n";
    }
    return 0;
}
有注释
cpp 复制代码
#include<bits/stdc++.h>  // 万能头文件,包含了C++常用的所有头文件
#define ll long long     // 宏定义:将long long简写为ll,方便书写

using namespace std;     // 使用标准命名空间std

/**
 * 快速幂函数:计算 (a^b) % mod 的值
 * 原理:将指数b转换为二进制形式,通过不断平方底数来减少计算次数
 * 时间复杂度:O(log b)
 * 
 * @param a 底数
 * @param b 指数
 * @param mod 模数
 * @return (a^b) % mod 的结果
 */
ll kusumi(ll a, ll b, ll mod){
    ll ans = 1;           // 初始化结果为1(任何数的0次方为1)
    
    while(b){             // 当指数b不为0时继续循环
        if(b & 1)         // 位运算:检查b的二进制最低位是否为1(等价于b % 2 == 1)
            ans = ans * a % mod;  // 如果当前位为1,将当前的a乘入结果并取模
        
        a = a * a % mod;  // a平方:a^(2^k) -> a^(2^(k+1)),并立即取模防止溢出
        b >>= 1;          // b右移一位:b = b / 2,处理下一位二进制位
    }
    
    return ans;           // 返回最终结果
}

int main(){
    // 输入输出优化:关闭C与C++的输入输出同步,解除cin与cout的绑定
    // 这样可以提高cin/cout的读写速度,适用于大量输入输出的情况
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    
    int t;                // 测试数据的组数
    cin >> t;
    
    while(t --){           // 循环处理每组测试数据
        int m, h;         // m: 模数  h: 数对的数量
        cin >> m >> h;
        
        ll ans = 0;       // 初始化累加和为0
        
        while(h --){      // 循环读入h对数对
            int a, b;     // a: 底数  b: 指数
            cin >> a >> b;
            
            // 计算 (a^b) % m 并累加到ans中
            ans += kusumi(a, b, m);
            ans %= m;      // 累加后立即取模,防止中间结果过大导致溢出
        }
        
        cout << ans << "\n";  // 输出当前测试数据的计算结果
    }
    
    return 0;             // 程序正常结束
}
相关推荐
Full Stack Developme1 小时前
哈希是什么
算法·哈希算法
薛定e的猫咪2 小时前
【AAAI 2025】基于扩散模型的昂贵多目标贝叶斯优化
论文阅读·人工智能·算法
Fox爱分享2 小时前
拼多多面试: 设计“砍一刀”算法,怎么防止被刷破产?90% 的人死在了“最后 0.01 元”
后端·算法·面试
NGC_66112 小时前
归并排序算法
java·数据结构·算法
你撅嘴真丑2 小时前
第十章-训练参考
算法
岛雨QA2 小时前
稀疏数组和队列「Java数据结构与算法学习笔记2」
数据结构·算法
沉在嵌入式的鱼2 小时前
温度嵌入式软件算法补偿方案及步骤
stm32·单片机·算法·温度传感器·温度补偿
岛雨QA2 小时前
数据结构和算法概述「Java数据结构与算法学习笔记1」
数据结构·算法