1. 程式人生 > 實用技巧 >【題解】POJ 1995 Raising Modulo Numbers

【題解】POJ 1995 Raising Modulo Numbers

Raising Modulo Numbers

題目傳送門

(以下由DeepL翻譯)

說明

人是不同的。有的人偷偷地看雜誌,裡面全是有趣的女孩的照片,有的人在地窖裡製造原子彈,
有的人喜歡使用Windows,有的人喜歡高難度的數學遊戲。
最新的市場調查顯示,這個細分市場至今被低估,缺乏這類遊戲。因此,這種遊戲被納入了KOKODáKH。
遊戲規則如下:
每個玩家選擇兩個數字Ai和Bi 然後把它們寫在紙條上. 其他人不能看到這些數字。
在特定的時刻,所有的玩家向其他人展示他們的數字。目標是確定包括自己在內的所有玩家的所有表示式${Ai}^{Bi}$的總和,
並確定除以給定數字M後的剩餘部分。根據選手的經驗,可以選擇更高的數字來增加難度。

你應該編寫一個計算結果的程式,並能夠找出誰贏得了遊戲。

輸入

輸入由Z個賦值組成。它們的數量由輸入的第一行出現的單個正整數Z給出。
然後是賦值。每個賦值以包含整數M的行開始(1 <= M <= 45000)。
總數將被除以這個數字。下一行包含玩家數量H (1 <= H <= 45000)。
接下來正好是H行。在每一行中,有兩個數字Ai和Bi用空格隔開。兩個數字不能同時等於零。
(看不下去了qwq,意思就是先是 T組資料 ,然後 取餘的數M, 然後 H個玩家, 在是Ai,Bi)

輸出

對於每一個語句,只有一行輸出。在這一行中,有一個數字,是表示式的結果。

\[({A1}^{B1}+{A2}^{B2}+...+{AH}^{BH})mod M \]

取樣輸入

3
16
4
2 3
3 4
4 5
5 6
36123
1
2374859 3029382
17
1
3 18132

取樣輸出

2
13195
13

資料來源

1999年CTU公開賽

思路分析:

就沒什麼好說的。直接套快速冪。

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll; typedef unsigned long long ull;

int T;
ll a, b, p, n, ans;

inline int qpm(ll a, ll b, ll p) {
    ll ans = 1 % p, t = a % p;
    while(b) {
        if(b & 1) ans = ans * t % p;
        t = t * t % p;
        b >>= 1;
    }
    return ans;
}

int main(){
    scanf("%d", &T);
	while(T --) {
		ans = 0;
		scanf("%lld%lld", &p, &n);
		for(int i = 0; i < n; i ++) {
			scanf("%lld%lld", &a, &b);
			ans = (ans+qpm(a, b, p)) % p;
		}
		printf("%lld\n", ans);
	}
    return 0;
}