一个式子a*b 对于乘数b来说,可以写成二进制形式,比如1001101。由乘法分配律:a * b = a * (b1 + b2 + b3 + ……) 那么对于a * 53 = a * 110101(二进制) = a * (100000 + 10000 + 100 + 1) = a * (100000 * 1 + 10000 * 1 + 1000 * 0 + 100 * 1 + 10 * 0 + 1 * 1).0
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long LL;
LL mul(LL a, LL b, LL mod) {
LL ans = 0;
while(b) {
if(b & 1) ans = (ans + a) % mod;
b >>= 1;
a = (a + a) % mod;
}
return ans;
}
int main() {
LL ans = mul(23423, 1231, 9034);
printf("%d\n", ans);
return 0;
}
Lucas定理是用来求C(n, m) % p(p为素数)的答案的
typedef long long LL;
using namespace std;
LL exp_mod(LL a, LL b, LL p) {
LL res = 1;
while(b != 0) {
if(b & 1) res = (res * a) % p;
a = (a * a) % p;
b >>= 1;
}
return res;
}
LL Comb(LL a, LL b, LL p) {
if(a < b) return 0;
if(a == b) return 1;
if(b > a - b) b = a - b;
LL ans = 1, ca = 1, cb = 1;
for(LL i = 0; i < b; ++i) {
ca = (ca * (a - i)) % p;
cb = (cb * (b - i)) % p;
}
ans = (ca * exp_mod(cb, p - 2, p)) % p;
return ans;
}
LL Lucas(int n, int m, int p) {
LL ans = 1;
while(n && m && ans) {
ans = (ans * Comb(n % p, m % p, p)) % p;
n /= p;
m /= p;
}
return ans;
}
int main() {
int n, m, p;
while(~scanf("%d%d%d", &n, &m, &p)) {
printf("%lld\n", Lucas(n, m, p));
}
return 0;
}