模运算规律总结
运算规则
模运算与基本四则运算有些相似,但是除法例外。其规则如下:
(a + b) % p = (a % p + b % p) % p (1)
(a – b) % p = (a % p – b % p) % p (2)
(a * b) % p = (a % p * b % p) % p (3)
(a^b) % p = ((a % p)^b) % p (4)
结合律:
((a+b) % p + c) % p = (a + (b+c) % p) % p (5)
((ab) % p * c)% p = (a * (bc) % p) % p (6)
交换律:
(a + b) % p = (b+a) % p (7)
(a * b) % p = (b * a) % p (8)
分配律:
((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p (9)
重要定理:
若a≡b (% p),则对于任意的c,都有(a + c) ≡ (b + c) (%p);(10)
若a≡b (% p),则对于任意的c,都有(a * c) ≡ (b * c) (%p);(11)
若a≡b (% p),c≡d (% p),则 (a + c) ≡ (b + d) (%p),(a – c) ≡ (b – d) (%p),
快速幂与矩阵快速幂
题解
这道题首先需要看到一个数理上的规律,首先对于k进制的数,我们可以把他写成如下形式
两式相减我们可以得到
可以看到每一个项都有一个
的项,那么左边对(k-1)取余显然结果为0,即
。同理,只要我们的
项不小于
,这个过程就会一直继续下去,我们记这个过程求出的所有
为
(我们总会碰到一项
,使得
),那么我们有:
根据上门上述的模运算规律,我们将左侧所有项相加
因为
已经比
小了,所以得到
那么只要我们得到N的值,就可以直接求出结果,现在问题变成了
,这么大的数据范围显然不可能pow水过,那么大数乘法+快速幂?太麻烦了求模运算不好施展。所以我们使用求模运算的性质,在求出N的过程中不断取模即可。
#include<iostream>
#include<string>
#include<string.h>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
using namespace std;
#define ll unsigned long long
#define MAX 250
#define inf 10000000
ll root(ll x, ll y, ll k) {
ll base = x, ans = 1;
while (y > 0) {
if (y & 1)ans = (ans % (k - 1)* base % (k - 1)) % (k - 1);
base = ((base % (k - 1))*(base % (k - 1))) % (k - 1); y >>= 1;
}
if (ans == 0)ans = k - 1;
return ans;
}
int main() {
ll x, y, k;
while (cin >> x >> y >> k) {
cout << root(x, y, k) << endl;
}
}