Timus[1055. Combinations]
原题地址: Timus[1055. Combinations]
类似于求n!尾部有多少个零,基于Legendre theorem。
#include <iostream> using namespace std; const int MAX_N = 50000; const int MAX_PRIMES = 5133; int N, M; int K; int primes[MAX_PRIMES]; int A[MAX_PRIMES]; int tag[((MAX_N - 1) / 2 + 31) >> 5]; bool test(int x) { return (tag[x >> 5] & (1 << (x & 0x1F))) != 0; } void set(int x) { tag[x >> 5] |= 1 << (x & 0x1F); } void input() { cin >> N >> M; } void initialize() { for (int i = 0; ((i << 1) + 3) * ((i << 1) + 3) <= N; ++i) { if (!test(i)) { for (int k = 2 * i * i + 6 * i + 3; (k << 1) + 2 < N; k += 2 * i + 3) { set(k); } } } K = 0; primes[K++] = 2; for (int i = 0; (i << 1) + 2 < N; ++i) { if (!test(i)) { primes[K++] = 2 * i + 3; } } } void process(int x, bool add) { for (int i = 0; i < K && primes[i] <= x; ++i) { int z = primes[i]; int y = x; while (y >= z) { if (add) { A[i] += y / z; } else { A[i] -= y / z; } y /= z; } } } int solve() { initialize(); if (2 * M > N) { M = N - M; } process(N, true); process(M, false); process(N - M, false); int ans = 0; for (int i = 0; i < K; ++i) ans += A[i] != 0; return ans; } int main() { input(); cout << solve() << endl; return 0; }

浙公网安备 33010602011771号