题解 P2613 模板有理数取余

Posted zhengkunjia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 P2613 模板有理数取余相关的知识,希望对你有一定的参考价值。

题目

题目描述

给出一个有理数 (c=frac{a}{b}),求 c mod 19260817 的值。

输入格式

一共两行。

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

输出格式

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

输入输出样例

输入

233
666

输出

18595654

说明/提示
对于所有数据 (0 <= a,b <= 10^{10001})

分析

模意义下,除以一个数等于乘它的逆元

高精度??输入long long化

因为可以随时对MOD = 19260817取余,所以可以用快读,边读边取余,最后得到一个int类型的a和b,而不用高精度存储

快速幂求逆元

注意到模数19260817是个质数,我们求b在模它意义下的逆元

由欧拉定理,若x,p互质,则(x ^ phi(p)/equiv 1(mod p))
若p是个质数,(phi(p)=p-1),就有(x^{p-1}/equiv 1(mod p))
在模p意义下,x的逆元是(x ^ {p - 2})
即b的逆元是(b ^ {19260817 - 2})

使用快速幂
代码

ll quick_mi_inv(ll c){
    ll t = MOD - 2;
    ll res = 1;
    while(t){
        if(t & 1){
            res *= c;
        }
        c = c*c;
        t >>= 1;
        c %= MOD;
        res %= MOD;
    }
    return res;
}

线性求逆元

//求1~n在模p意义下的逆元
//跟这个题没关系

int inv[N] , n , p;
cin >> n >> p;
inv[1]=1;
for (int i = 2 ; i <= n ; i++)

{

    int a = p / i;
    
    int b = p % i;
    
    inv[i] = (p - inv[b]*a) % p;
}

Angry!

因为0不能作除数,若b=0,无解
逆元的存在?
因为p是质数,所以b和p互质(如果不互质,b模完就成0了),所以b在模p意义下的逆元一定存在
综上所述:
当且仅当b=0时,输出"Angry!"

没了然后就代码了

代码实现

#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define F(a,b,c) for(int a = b; a <= c; a++)
#define UF(a,b,c) for(int a = b; a >= c; a--)
#define MOD 19260817 
using namespace std;
typedef long long ll;
ll a, b, c; 
ll read(){
    char c = getchar();
    int f = 1;
    ll res = 0;
    while(c < '0' || c > '9'){
        if(c == '-')    f = -1;
        c = getchar();
    }
    while(c <= '9' && c >= '0'){
        res *= 10;
        res += c - '0';
        res %= MOD;
        c = getchar();
    }
    return res * f;
}

ll quick_mi_inv(ll c){
    ll t = MOD - 2;
    ll res = 1;
    while(t){
        if(t & 1){
            res *= c;
        }
        c = c*c;
        t >>= 1;
        c %= MOD;
        res %= MOD;
    }
    return res;
}
int main(){
    a = read();
    b = read();
    if(b == 0){
        cout << "Angry!" << endl;
        return 0;
    }
    b = quick_mi_inv(b);
    cout << (a * b % MOD + MOD) % MOD << endl;
    return 0;
}


以上是关于题解 P2613 模板有理数取余的主要内容,如果未能解决你的问题,请参考以下文章

Luogu P2613 模板有理数取余

[模板] 有理数取余

有理数取余

Luogu 题解 P1226 [模板] 快速幂||取余运算

洛谷 P1226 取余运算||快速幂 题解

题解PTA团体程序设计天梯赛L1-009 N个数求和 (20 分) Go语言|Golang