有理数取余[模板]
有理数取余[模板]
简单总结几下
设p=19260817
-
\(\frac{a}{b} \mod p\)
令\(x=\frac{a}{b} (\mod p)\)
同乘性,两边同乘\(b\),\(x*b=\frac{a}{b}*b (\mod p)\)
化简为 \(b*x=a(\mod p)\) (1)
类似求线性同余方程的方法
先考虑是否存在 \(b*x_0=1(\mod p)\),如果存在最小正整数\(x_0\)使得式子成立
再利用同乘性两边同乘a,\(a*b*x_0=a(\mod p)\)
与上式(1)对比 \(x=a*x_0 (\mod p)\) 求\(a*x_0 \mod p\)即可
-
\(a和b\)太大了怎么办
快读时取模即可,取模原数并不影响值
比如\((b\mod p)*x=a \mod p(\mod p)\) -
无解情况
分母为0无解
\(1 \mod gcd(b,p)!=0\)即\(gcd(b,p)!=1\)
-
code
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int mod=19260817;
int a,b;
int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
x=x%mod;
ch=getchar();
}return x*f;
}
int exgcd(int a,int b,int &x,int &y){
if(!b){
x=1,y=0;
return a;
}
int d=exgcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-(a/b)*y;
return d;
}
int main(){
a=read(),b=read();
if(b==0){
puts("Angry");
return 0;
}
int x,y;
int d=exgcd(b,mod,x,y);
x=(x%mod+mod)%mod;
printf("%lld\n",a*(long long )x %mod);return 0;
return 0;
}