[atARC138E]Decreasing Subsequence
对a_{i}\ne 0连边(i,a_{i}),得到的图即由若干编号严格递减的路径和自环构成
考虑(i_{j},a_{i_{j}})所在的路径,按照a_{i_{j}}左侧和i_{j}右侧将点集划分为L和R(k条路径取并)
另外,需要特判a_{i_{1}}=i_{1}的情况,具体做法类似,以下不作考虑
枚举|L|和||R|,并依次进行以下步骤确定贡献:
1.在n个点中选择|L|+|R|个点(两者之间有序)
2.将这|L|和|R|个点分别划分为k条路径(两者之间连边确定)
3.将剩下的n-|L|-|R|个点构成一张合法的图
显然均可简单dp得到(实际就是第二类斯特林数),时间复杂度为o(n^{2}),可以通过
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 5005 4 #define mod 1000000007 5 #define ll long long 6 int n,m,ans,C[N][N],g[N][N],sum[N],f[N]; 7 int main(){ 8 scanf("%d%d",&n,&m); 9 for(int i=0;i<=n;i++){ 10 C[i][0]=C[i][i]=1; 11 for(int j=1;j<i;j++)C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod; 12 } 13 g[0][0]=1; 14 for(int i=1;i<=n;i++) 15 for(int j=1;j<=i;j++)g[i][j]=(g[i-1][j-1]+(ll)j*g[i-1][j])%mod; 16 for(int i=0;i<=n;i++){ 17 for(int j=0;j<=i;j++)sum[i]=(sum[i]+g[i][j])%mod; 18 for(int j=0;j<=i;j++)f[i]=(f[i]+(ll)C[i][j]*sum[i-j])%mod; 19 } 20 for(int i=m;i<=n;i++) 21 for(int j=m;j<=n;j++){ 22 if (i+j<=n)ans=(ans+(ll)C[n][i+j]*g[i][m]%mod*g[j][m]%mod*f[n-i-j])%mod; 23 if (i+j-1<=n)ans=(ans+(ll)C[n][i+j-1]*g[i-1][m-1]%mod*g[j-1][m-1]%mod*f[n-i-j+1])%mod; 24 } 25 printf("%d\n",ans); 26 return 0; 27 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步