T many times, but also want to use mutimap violence to decompose the prime factor of each number. Later, the minimum prime factor for each number was recorded.
#include <bits/stdc++.h> using namespace std; typedef long long ll; int n, m, MOD; const int SIZE = 1e6, SIZEP = 8e4; int p2[SIZE + 5], p5[SIZE + 5]; int p[SIZEP + 5], ptop; int minp[SIZE + 5]; void init() { for(int i = 2; i <= SIZE; i *= 2) { for(int j = i; j <= SIZE; j += i) p2[j] ++; } for(int i = 5; i <= SIZE; i *= 5) { for(int j = i; j <= SIZE; j += i) p5[j] ++; } minp[1] = 1; for(int i = 2; i <= SIZE; i++) { if(!minp[i]) { p[++ptop] = i; minp[i] = ptop; } for(int j = 1, t; j <= ptop && (t = i * p[j]) <= SIZE; j++) { minp[t] = j; if(i % p[j] == 0) break; } } //cout<<ptop<<endl; } int cntp[SIZEP + 5]; void cnt(int n, int d) { while(n != 1) { cntp[minp[n]] += d; n /= p[minp[n]]; } } int qpow(ll x, int n) { ll res = 1; while(n) { if(n & 1) res = res * x % MOD; x = x * x % MOD; n >>= 1; } return res; } int calc() { memset(cntp, 0, sizeof(cntp)); m = min(n - m, m); for(int i = 1; i <= m; ++i) { cnt(n - i + 1, 1); cnt(i, -1); } int min10 = min(cntp[1], cntp[3]); cntp[1] -= min10, cntp[3] -= min10; printf("%d ", min10); ll ans = 1; for(int i = 1; i <= ptop; ++i) ans = ans * (qpow(p[i], cntp[i])) % MOD; return ans % MOD; } int main() { #ifdef Yinku freopen("Yinku.in", "r", stdin); #endif // Yinku init(); while(~scanf("%d%d%d", &n, &m, &MOD)) printf("%d\n", calc()); }
In fact, this is a factorial (DQ method), so the contribution of each quality factor within the factorial can be calculated. Specifically, 2 contributes n/2, 4 contributes n/4 2, 8 contributes n/8 2.
Using the above method, each prime factor contributes a log of 80,000 logns, while my method is 1000,000 logns, and my pretreatment of p2 and p5 is not linear (the latter two white processes are found).
Binary memset, psychotic.
#include <bits/stdc++.h> using namespace std; typedef long long ll; int n, m, MOD; const int SIZE = 1e6, SIZEP = 8e4; int p[SIZEP + 5], ptop; int minp[SIZE + 5]; void init() { minp[1] = 1; for(int i = 2; i <= SIZE; i++) { if(!minp[i]) { p[++ptop] = i; minp[i] = ptop; } for(int j = 1, t; j <= ptop && (t = i * p[j]) <= SIZE; j++) { minp[t] = j; if(i % p[j] == 0) break; } } //cout<<ptop<<endl; } int maxptop; int cntp[SIZEP + 5]; void cnt(int n, int d) { /*while(n != 1) { cntp[minp[n]] += d; n /= p[minp[n]]; }*/ for(int i=1;i<=maxptop;++i){ int tmp=n; while(tmp/=p[i]){ cntp[i]+=tmp*d; } } } int qpow(ll x, int n) { ll res = 1; while(n) { if(n & 1) res = res * x % MOD; x = x * x % MOD; n >>= 1; } return res; } int calc() { maxptop=min(int(lower_bound(p+1,p+1+ptop,n)-p),ptop); memset(cntp, 0, sizeof(cntp[0])*(maxptop+1)); /*m = min(n - m, m); for(int i = 1; i <= m; ++i) { cnt(n - i + 1, 1); cnt(i, -1); }*/ cnt(n,1); cnt(m,-1); cnt(n-m,-1); int min10 = min(cntp[1], cntp[3]); cntp[1] -= min10, cntp[3] -= min10; printf("%d ", min10); ll ans = 1; for(int i = 1; i <= maxptop; ++i){ if(cntp[i]) ans = ans * (qpow(p[i], cntp[i])) % MOD; } return ans % MOD; } int main() { #ifdef Yinku freopen("Yinku.in", "r", stdin); #endif // Yinku init(); while(~scanf("%d%d%d", &n, &m, &MOD)) printf("%d\n", calc()); }