• P2613 【模板】有理数取余(高精度数的取余问题+扩展欧几里德)


    题目描述

    给出一个有理数 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;

    }

  • 相关阅读:
    PHP 标量类型与返回值类型声明
    如何使用 PHP 语言来编码和解码 JSON 对象
    mongodb的读写分离
    [FWT] UOJ #310. 【UNR #2】黎明前的巧克力
    drcom 不耍流氓
    drcom 不耍流氓
    Visual Studio 自定义项目模板
    Visual Studio 自定义项目模板
    Visual Studio 自定义项目模板
    【广告】win10 uwp 水印图床 含代码
  • 原文地址:https://www.cnblogs.com/ssfzmfy/p/14848671.html
Copyright © 2020-2023  润新知