【出栈序列个数】 火车进出站问题
传送门
题意
\(1\sim n\)的序列依次进栈,出栈的排列有多少种
数据范围
\(1\leq n\leq 6\times 10^{4}\)
题解
Catalan数,求组合数即可
Code
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=120010;
ll primes[N],cnt,sum[N];
ll ans[N], tt, n;
bool st[N];
void get_primes(ll n){
for (int i = 2; i <=n ; ++i) {
if(!st[i]) primes[cnt++] = i;
for (int j = 0; primes[j] <= n / i ; ++j) {
st[primes[j] * i] = true;
if(i % primes[j] == 0) break;
}
}
}
int get(ll n, ll p) {
int res = 0;
while(n){
res += n / p;
n /= p;
}
return res;
}
void multi(int b) {
ll t = 0;
for (int i = 0; i <= tt; i ++ ) {
ans[i] = ans[i] * b + t;
t = ans[i] / 1000000000;
ans[i] %= 1000000000;
}
while (t) {
ans[++tt] = t % 1000000000;
t /= 1000000000;
}
}
void out() {
printf("%lld", ans[tt]);
for (int i = tt - 1; i >= 0; i -- )
printf("%09lld", ans[i]);
cout << endl;
}
int main(){
scanf("%lld", &n);
get_primes(2 * n);
for (int i = 0; i < cnt ; ++i) {
ll p = primes[i];
sum[i] = get(2 * n, p) - get(n, p) - get(n + 1, p);
}
ans[0] = 1;
for (int i = 0; i < cnt; ++i)
for (int j = 1; j <= sum[i]; ++j)
multi(primes[i]);
out();
}