题解:CF2063F1 Counting Is Not Fun (Easy Version)
思路
看到括号不难想到卡特兰数,再看样例可以发现卡特兰数是对的。
所以不难发现
接下来,每次确定好对位置,因为是操作二形成的,所以可以看成是剥离出来的一个子问题。
每次再把每个子问题的答案相乘即可。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int read()
{
int res = 0,f = 1;
char ch = getchar();
while (ch<'0'||ch>'9') f = (ch=='-'?-1:1),ch = getchar();
while (ch>='0'&&ch<='9') res = (res<<3)+(res<<1)+(ch^48),ch = getchar();
return res*f;
}
void write(int x)
{
if (x<0) putchar('-'),x=-x;
if (x>9) write(x/10);
putchar(x%10+'0');
}
void writech(int x,char ch){write(x),putchar(ch);}
const int N = 1e4+5,MOD = 998244353;
int n;
int t[N],cnt[N];
int fac[N],c[N];
int qpow(int a,int b)
{
int res = 1;
while (b)
{
if (b&1) res=res*a%MOD;
a=a*a%MOD;
b>>=1;
}
return res;
}
int inv(int a,int m)
{
return qpow(a,m-2);
}
int C(int n)
{
return fac[2*n]*inv(fac[n],MOD)%MOD*inv(fac[n+1],MOD)%MOD;
}
signed main()
{
fac[0]=1;
for (int i = 1; i < N; i++) fac[i]=fac[i-1]*i%MOD;
for (int i = 0; i < N; i++) c[i]=C(i);
int T=read();
while (T--)
{
n=read();
for (int i = 1; i <= 2*n; i++) t[i]=0;
writech(c[n],' ');
for (int i = 1; i <= n; i++)
{
int l=read(),r=read();
for (int j = 0; j <= n; j++) cnt[j]=0;
t[l]=i,t[r]=-i;
stack<int> s;
s.push(0);
for (int j = 1; j <= 2*n; j++)
{
if (t[j]==0) ++cnt[s.top()];
else if (t[j]<0) s.pop();
else s.push(t[j]);
}
int ans = 1;
for (int j = 0; j <= n; j++) ans=ans*c[cnt[j]/2]%MOD;
writech(ans,' ');
}
puts("");
}
return 0;
}