题目描述
给出一个有理数 c=a/b,求 c mod 19260817 的值。
输入格式
一共两行。
第一行,一个整数 a。
第二行,一个整数 b。
输出格式
一个整数,代表求余后的结果。如果无解,输出 Angry!
。
输入输出样例
233 666
18595654
说明/提示
对于所有数据,保证 0≤a≤10^10001,1≤b≤10^10001,且 a,b 不同时是 19260817 的倍数
分析:
第一步:
(a/b) mod 19260817 =a*(1/b)mod 19260817=(a mod 19260817)*((1/b)mod 19260817)
(1/b)mod 19260817 一个小数对 一个整数取模,有何意义呢?结果是多少呢?
根据乘法逆元,在模意义下有
b*x≡1(mod p), 假设p=19260817,x为b的逆元
(1/b)mod p =(1 (mod p))/b mod p=((b*x)mop)/b mod p =(b*x)/b mod p= x mod p
则(a/b) mod p=ax mod p ,这样便将整数的同余推广到了有理数范围内。
则ax mod p,即为所求的答案
又因为题目中b是已知的,需要把x(b的逆元求出来)
b*x≡1(mod p)
等价于 bx+py=1的最小正整数解,可以使用扩展欧几里德求
如果gcd(b,p)=1,则有解,否则无解
最小正整数解:(x%p+p)%p
本题的最小正整数解 (ax%p+p)%p
以上分析基于非高精度的数,对于 0≤a≤10^10001,1≤b≤10^10001这样的高精度数又该如何处理呢?
第二步:
假设 a=x1*10^10001+x2*10^10000+x3*10^9999+...+x(10001)*10^0
则 a%p=(x1*10^10001+x2*10^10000+x3*10^9999+...+x(10001)*10^0)%p
=((x1*10^10001%p)+(x2*10^10000%p)+(x3*10^9999%p)+...+(x(10001)*10^0%p))%p
=((x1%p)*(10^10001%p)+(x2%p)*(10^10000%p)+(x3%p)*(10^9999%p)+...+(x(10001)%p)*(10^0%p))%p
a是高精度,可以按字符串读入,然后从高位到低位依次处理:
string s;
long long a=0;
cin>>s;
n=s.size();
for(int i=0;i<n;i++){
a=(a*10+s[i]-48)%p;
}