《算法竞赛进阶指南》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;             // 程序正常结束
}
相关推荐
做怪小疯子5 分钟前
Leetcode刷题——8.重叠区间
算法·leetcode·职场和发展
2401_857865238 分钟前
C++模块接口设计
开发语言·c++·算法
add45a18 分钟前
嵌入式C++低功耗设计
开发语言·c++·算法
DeepModel20 分钟前
【概率分布】指数分布(Exponential Distribution)原理、推导与实战
python·算法·概率论
_饭团25 分钟前
指针核心知识:5篇系统梳理3
c语言·数据结构·算法·leetcode·面试·学习方法·改行学it
2401_8747325327 分钟前
C++中的状态模式
开发语言·c++·算法
BB学长27 分钟前
LBM vs FVM:谁才是 CFD 的未来?
人工智能·算法·机器学习
闻缺陷则喜何志丹27 分钟前
【枚举】P6786「SWTR-6」GCDs & LCMs|普及+
c++·算法·洛谷
m0_716667071 小时前
实时数据压缩库
开发语言·c++·算法
dapeng28701 小时前
多协议网络库设计
开发语言·c++·算法