题目描述

给出一个有理数 c=a/b,求 mo19260817 的值。

输入格式

一共两行。

第一行,一个整数 a
第二行,一个整数 b

输出格式

一个整数,代表求余后的结果。如果无解,输出 Angry!

 

输入输出样例

输入 #1
233
666
输出 #1
18595654

说明/提示

对于所有数据,保证 0a10^10001,1b10^10001,且 a,b 不同时是 19260817 的倍数

分析:

第一步:

(a/b) mo19260817 =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

 

以上分析基于非高精度的数,对于 0a10^10001,1b10^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;

}