bzoj1485 有趣的数列
传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1485
【题解】
Catalan数,注意不能直接用逆元,需要分解质因数。
1 # include <bits/stdc++.h> 2 using namespace std; 3 4 const int M = 5e5 + 10, N = 2e6 + 10; 5 6 int isp[N]; 7 int p[M], pn; 8 int n, mod; 9 int times[M]; 10 11 inline int pwr(int a, int b) { 12 int ret = 1; 13 while(b) { 14 if(b&1) ret = 1ll * ret * a % mod; 15 a = 1ll * a * a % mod; 16 b >>= 1; 17 } 18 return ret; 19 } 20 21 int main() { 22 cin >> n >> mod; 23 for (int i=2; i<=n+n; ++i) isp[i] = 1; 24 for (int i=2; i<=n+n; ++i) { 25 if(isp[i]) { 26 p[++pn] = i; 27 isp[i] = pn; 28 for (int j=i+i; j<=n+n; j+=i) 29 isp[j] = 0; 30 } 31 } 32 for (int i=n+1; i<=n+n; ++i) { 33 int t = i; 34 for (int j=1; j<=pn; ++j) { 35 if(t % p[j] == 0) 36 while(t % p[j] == 0) ++times[j], t /= p[j]; 37 if(t == 1) break; 38 if(isp[t]) { 39 ++ times[isp[t]]; 40 break; 41 } 42 } 43 } 44 // for (int i=1; i<=5; ++i) 45 // cout << p[i] << ' ' << times[i] << endl; 46 for (int i=2; i<=n+1; ++i) { 47 int t = i; 48 for (int j=1; j<=pn; ++j) { 49 if(t % p[j] == 0) 50 while(t % p[j] == 0) --times[j], t /= p[j]; 51 if(t == 1) break; 52 if(isp[t]) { 53 -- times[isp[t]]; 54 break; 55 } 56 } 57 } 58 59 int ans = 1; 60 for (int i=1; i<=pn; ++i) 61 if(times[i]) ans = 1ll * ans * pwr(p[i], times[i]) % mod; 62 63 cout << ans; 64 65 return 0; 66 }