1636:【例 6】计算器
题目描述
原题来自:SDOI 2011
你被要求设计一个计算器完成以下三项任务:
- 给定 y,z,p,计算 yzmodp 的值;
- 给定 y,z,p,计算满足 x×y≡z(modp) 的最小非负整数 x;
- 给定 y,z,p,计算满足 yx≡z(modp) 的最小非负整数 x。
输入格式
输入包含多组数据。
第一行包含两个正整数 T,K 分别表示数据组数和询问类型(对于一个测试点内的所有数据,询问类型相同);
以下 T 行每行包含三个正整数 y,z,p,描述一个询问。
输出格式
对于每个询问,输出一行答案。
对于询问类型 2 和 3,如果不存在满足条件的,则输出 Orz, I cannot find x!,注意逗号与 I 之间有一个空格。
样例
样例输入 #1(询问类型 1)
3 1
2 1 3
2 2 3
2 3 3
样例输出 #1
2
1
2
样例解释 #1
- 类型 1:计算 yzmodp。
- 第一组:21mod3=2
- 第二组:22mod3=4mod3=1
- 第三组:23mod3=8mod3=2
样例输入 #2(询问类型 2)
3 2
2 1 3
2 2 3
2 3 3
样例输出 #2
2
1
0
样例解释 #2
- 类型 2:解方程 x×y≡z(modp)。
- 第一组:x×2≡1(mod3),解为 x=2(因为 2×2=4≡1(mod3))。
- 第二组:x×2≡2(mod3),解为 x=1(1×2=2)。
- 第三组:x×2≡3(mod3),注意 3mod3=0,所以方程是 2x≡0(mod3),解为 x=0(因为 2×0=0)。注意 x 可以取 0,且 0 是最小非负整数解。
数据范围与提示
对于全部数据:
- 1≤y,z,p≤109
- 1≤T≤10
- 保证 p 为质数
时空限制
- 时间限制:1000 ms
- 内存限制:524288 KB
注意:本题三个子任务分别对应:
- 快速幂取模。
- 线性同余方程(求逆元)。
- 离散对数(BSGS算法)。
由于 p 是质数,求解较为方便。
任务 1:直接用快速幂计算 yzmodp。
任务 2:方程 x×y≡z(modp)。如果 y≡0(modp),则方程化为 0≡z(modp),如果 z≡0,则 x 可取任意整数,最小非负整数解为 0;否则无解。如果 y≡0(modp),由于 p 是质数,y 有逆元,x≡z×y−1(modp),用扩展欧几里得或费马小定理求逆元(因为 p 是质数,yp−2modp 就是逆元)。注意求最小非负整数解。
任务 3:离散对数问题 yx≡z(modp),用 BSGS算法(Baby-Step Giant-Step)。由于 p 是质数,且 p≤109,但 T≤10,可以使用 BSGS。注意特判:
- 如果 y≡0(modp),则 yx≡0,如果 z≡0 则 x=1(因为 01=0),但 x=0 时 y0=1(如果 y=0,00 未定义,通常不考虑)。实际上,y=0 时,x>0 则 yx=0,所以如果 z=0 且 y=0,则 x 最小为 1(如果 z=0 则无解)。
- 如果 z≡1(modp),则 x=0 是解(因为 y0=1)。
- 一般情况,BSGS 算法步骤:
- 设 m=⌈p⌉。
- 预处理 y0,y1,…,ym−1 模 p 的值,存入哈希表(或有序表)。
- 计算 y−m(即 ym 的逆元)。
- 令 t=z,对于 i 从 0 到 m−1,检查 t 是否在哈希表中,如果在,则找到解 x=i×m+j(其中 j 是对应的指数)。否则令 t=t×y−mmodp。
- 如果找不到,则无解。
注意 BSGS 算法中 y 和 p 不一定互质,但 p 是质数且 y=0(modp) 时它们互质,可以求逆元。如果 y≡0(modp),已经特判。
由于 p≤109,m≈31623,哈希表大小可行。注意使用 unordered_map 或手写哈希以提高速度。