题解 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 模板有理数取余的主要内容,如果未能解决你的问题,请参考以下文章