AGC055C
Legitimity · · 题解
solution
考虑寻求存在满足条件的排列
首先显然的是假设整个序列的 LIS 长度为
下面定义必经点、非必经点、无用点。
- 若位置
i 在所有 LIS 中,即去掉位置i 后 LIS 长度减少,那么称i 为必经点,有A_i=k-1 。 - 若位置
i 在某个 LIS 中,且去掉位置i 后 LIS 长度不变,那么称i 为非必经点,有A_i=k 。 - 若位置
i 不在任何一个 LIS 中,那么称i 为无用点,有A_i=k 。
首先我们考虑整个
- 全都是
k-1 ,即全是必经点,显然满足条件的只有k=n 时P=\{1,2,\ldots,n-1,n\} 。 - 全都是
k ,考虑非必经点一定是成对出现,当一对点中的一个点被删掉,另一个点能发挥等效的作用,即一对点对 LIS 产生长度为1 的贡献,那么可得n 个非必经点至多产生\lfloor\dfrac{n}{2}\rfloor 的贡献,必要条件就是k\leq \lfloor\dfrac{n}{2}\rfloor ,这个序列由2k 个非必经点和n-2k 个无用点构成。这个条件也是充分的,考虑形如P=\{n-k+1,n-k,\ldots n,n-2k+1,\ldots\}
接下来就只考虑
分析出了必要条件是
设
我们首先考虑填上无用点,考虑对于前
之后考虑非必经点被必经点划分成了若干段(
于是我们证明了充分性。
之后考虑如何数这个东西,枚举必经点数量
code
int n,m,ans;
int C[5005][5005];
signed main(){
//file();
n=read(),m=read(),djq=read(); C[0][0]=1;
rep(i,n) C[i][0]=1;
rep(i,n) rep(j,i) C[i][j]=add(C[i-1][j-1],C[i-1][j]);
ans=min(m,n/2)-1+(m>=n-1);
rep(i,min(n-1,m))
for(rg int j=0;j*2+i<=n;++j)
if(min(i+j,m)>=max(3,i))
pls(ans,1ll*C[i+1][n-i-j*2]*C[i+j][j]%djq*(min(i+j,m)-max(3,i)+1)%djq);
printf("%d",ans);
return 0;
}