有理数取余[模板]

有理数取余[模板]

简单总结几下

设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;
}
posted @ 2021-08-23 18:57  归游  阅读(84)  评论(0编辑  收藏  举报