EXPORT S64 _modPow(S64 value, S64 exponent, S64 modulus) { THROWDBG(value < 0, 0xe9170006); THROWDBG(exponent < 0, 0xe9170006); THROWDBG(modulus < 0, 0xe9170006); return (S64)ModPow((U64)value, (U64)exponent, (U64)modulus); }
//@ Main Function int main() { for (int i = 1; i < maxK; i++) invi[i] = ModPow(i, mod - 2); int _case; LL n, m, k; scanf("%d", &_case); for (int __case = 1; _case; _case--, __case++) { scanf("%lld%lld%lld", &n, &m, &k); LL cmk = 1; for (int i = 1; i <= k; i++) cmk = cmk * (m - i + 1) % mod * invi[i] % mod; ck[0] = 1; for (int i = 1; i <= k; i++) ck[i] = ck[i - 1] * (k - i + 1) % mod * invi[i] % mod; LL ans = 0; for (int i = k, sgn = 1; i >= 1; i--, sgn = -sgn) ans = (ans + sgn * (i * ModPow(i - 1, n - 1) % mod * ck[i] % mod)) % mod; ans = (ans + mod) % mod * cmk % mod; printf("Case #%d: %lld\n", __case, ans); } return 0; }
Shamir::Shares Shamir::split(uint256 secret) const { Shares shares; std::vector<CBigNum> coef; coef.push_back(CBigNum(secret)); for (unsigned char i = 1; i < _quorum; ++i) coef.push_back(rnd()); for (unsigned char x = 1; x <= _shares; ++x) { CBigNum accum = coef[0]; for (unsigned char i = 1; i < _quorum; ++i) accum = (accum + (coef[i] * ModPow(CBigNum(x), i, _order))) % _order; shares[x] = accum.getuint256(); } return shares; }
/* 繰り返し2乗法 * (x ** n) % MODを返す. * 計算量 log(n) */ Long ModPow(Long x, Long n, Long Mod) { if (n == 0) return 1; if (n % 2 == 1) return x * ModPow(x, n - 1, Mod) % Mod; Long r = ModPow(x, n / 2, Mod); return r * r % Mod; }
EXPORT Bool _prime(S64 n) { if (n <= 1) return False; if ((n & 1) == 0) return n == 2; if (n <= 1920000) { if (n == 3) return True; if (n % 6 != 1 && n % 6 != 5) return False; S64 m = n / 6 * 2 + (n % 6 == 1 ? 0 : 1); size_t size; const U8* primes_bin = GetPrimesBin(&size); return (primes_bin[m / 8] & (1 << (m % 8))) != 0; } // Miller-Rabin primality test. U64 enough; if (n < 2047) enough = 1; else if (n < 1373653) enough = 2; else if (n < 25326001) enough = 3; else if (n < 3215031751) enough = 4; else if (n < 2152302898747) enough = 5; else if (n < 3474749660383) enough = 6; else if (n < 341550071728321) enough = 7; else if (n < 3825123056546413051) enough = 9; else { // n < 2^64 < 318665857834031151167461 enough = 12; } { U64 d = (U64)n - 1; U64 s = 0; while ((d & 1) == 0) { s++; d >>= 1; } for (U64 i = 0; i < enough; i++) { U64 x = ModPow(Primes[i], d, (U64)n); U64 j; if (x == 1 || x == (U64)n - 1) continue; Bool probablyPrime = False; for (j = 0; j < s; j++) { x = ModPow(x, 2, (U64)n); if (x == (U64)n - 1) { probablyPrime = True; break; } } if (!probablyPrime) return False; } return True; } }