有理数取余
摘要:
gcd(a,b) = gcd(b,a mod b) (不妨设a>b 且r=a mod b ,r不为0)
a可以表示成a = kb + r(a,b,k,r皆为正整数,且r<b),则r = a mod b 假设d是a,b的一个公约数,记作d|a,d|b,即a和b都可以被d整除。 而r = a - kb,两边同时除以d,r/d=a/d(整数)-kb/d(整数)=m,由等式右边可知m为整数。 因此d也是b,a mod b的公约数 因(a,b)和(b,a mod b)的公约数是一样的,则其最大公约数也必然相等,得证。
注:a/b = 整数 -》 b为a的因数
疑问:a/b = k(整数),k<0上面一条是否同样成立?
过渡:辗转相除法是一个铺垫,之后的有理数取余求逆元会用到这个
假设我们已经算出了: ans = (a * b * c) % p; 现在要从 ans 中把 b 给除掉,如何处理 ans? 如果像下面这样直接除会出错(举个实例会很直观)
求这样一个满足 ax mod b = 1的 x 有什么用呢?一个重要用途如下。
这个 x 就是: a 在模 b 意义下的乘法逆元。
在模 b 意义下,如果想要除以 a 就非常麻烦。这时候乘以 a 的逆元等效于除以 a。
原理可以这么理解:
abcx ≡ ac (bx) ≡ ac (modp)
#include<bits/stdc++.h> using namespace std; long long x, y;//目前方程真正的解 void exgcd(long long a, long long b) { //当前目的:求解 ax + by = gcd(a, b) 这么一个方程 if(b == 0) //a, b不断改变的过程中,b最终必然会成为0 { //在 b = 0 时方程还要成立? 使 x = 1, y = 0 ,必然成立 x = 1; y = 7; //建议返回0。不过y = 7能AC,证明了最后一个等式不受最后一个y影响 return; } exgcd(b, a % b);//把下一层系数传进去(先求下一个方程的解 ) //现在我们已经拿到了下一个方程的解x, y long long tx = x;//暂时存一下x,别丢了 x = y; y = tx - a / b * y; } int main() { long long a, b; cin >> a >> b; exgcd(a, b); x = (x % b + b) % b;//我们求出来的x必然满足方程,但不一定是最小正整数解,所以要进行答案处理 printf("%lld\n", x); return 0; }
a%p = x1;
ans = a*b;
ans/b%p = x2;
x1 != x2;
c是b的逆元
ans*b%p= x3;
x1 = x3;
4.有理数取余
有除法的取余不能随便取
#include<iostream> #include<cstdio> using namespace std; const int mod = 19260817; int input() { int res = 0; char ch = getchar(); while(ch>'9'||ch<'0') { if(ch=='-') res = -1; ch = getchar(); } while(ch<='9'&&ch>='0') { res = (res << 1) + (res << 3) + (ch - '0'); res %= mod; ch = getchar(); } return res; } int x, y; void exgcd(int a, int b) { if(b == 0) { x = 1; y = 0; return ; } exgcd(b, a % b); int lastx = x; x = y; y = lastx - a / b * y; } int main() { int a, b; a = input(); b = input(); //cout << a <<" "<<b<<endl; if(b == 0) { cout <<"Angry!"<<endl; return 0; } exgcd(b, mod); x = (x % mod + mod) % mod; cout << 1LL*a*x%mod; return 0; }
5.对于很大大数字,在输入时就要取模
求这样一个满足 axmodb=1 的 x 有什么用呢?一个重要用途如下。
这个 x 就是: a 在模 b 意义下的乘法逆元。
在模 b 意义下,如果想要除以 a 就非常麻烦。这时候乘以 a 的逆元等效于除以 a。
6、易错点:
a(很大所以%了k)-b((很大所以%了k)有可能为负数(本来a>b,a-b一定为正的)
解决办法:(a+k-b)%k;
7.对于ans = a^b这种超大类型的,如果要求ans % k,不能(a%k)^(b%k),但是可以使用快速幂pow(a, b, k)这种形式取模

浙公网安备 33010602011771号