1. 程式人生 > >bzoj 1485 有趣的數列

bzoj 1485 有趣的數列

ref 有趣 img geo http 題解 names mod catalan數

傳送門: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 }
View Code

bzoj 1485 有趣的數列