ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ARC138E Decreasing Subsequence

2022-04-11 09:01:31  阅读:216  来源: 互联网

标签:return int cmd Subsequence maxn Bmatrix Decreasing mul ARC138E


\(\texttt{或许更好的阅读体验}\)

\(\texttt{link}\)

第一步是巧妙的转化:对于 \(a_i>0\),连边 \((i,a_i-1)\)。

对于每个序列 \(a\),连边后形成若干条链

假设选出的 \(k\) 个点为 \(b_1,b_2,...,b_k\),并且 \(b_1<b_2<...<b_k\),对应的 \(a_{b_1}-1,...,a_{b_k}-1\) 为了方便记作 \(c_1,c_2,...,c_k\),则有:

\[c_k<c_{k-1}<...<c_1<b_1<b_2<...<b_k \]

这可以由 \(b_1>c_1\),\(c\) 递减,\(b\) 递增推导出来。

也就是说,在 \(a\) 确定的前提下,在 \([0,n]\) 中选出 \(2k\) 个点,它们对应的子序列有且仅有一种

考虑枚举前 \(k\) 个点以及所在链上的其他点的个数 \(i\),后 \(k\) 个点以及所在链上的其他点的个数 \(j\),则方案数为:

\[\dbinom{n+1}{i+j}\begin{Bmatrix}i\\k\end{Bmatrix}\begin{Bmatrix}j\\k\end{Bmatrix}\sum\limits_{x=1}^{n+1-i-j}\begin{Bmatrix}n+1-i-j\\x\end{Bmatrix} \]

将 \(i\) 个点分成 \(j\) 条链的方案数等价于第二类斯特林数,因为链上总是由编号大的指向编号小的。

注意一下实现做个前缀和就可以做到 \(\mathrm{O(n^2)}\)。

\(\texttt{Code:}\)

#include <bits/stdc++.h>
using namespace std;
const int cmd = 1e9 + 7;
inline int add(int a, int b) {a += b; return a < cmd ? a : a - cmd;}
inline int sub(int a, int b) {a -= b; return a < 0 ? a + cmd : a;}
inline int mul(int a, int b) {return 1ll * a * b % cmd;}
int fpow(int a, int b) {
    int res = 1;
    for (; b; b >>= 1, a = mul(a, a))
        if (b & 1) res = mul(res, a);
    return res;
}
const int maxn = 5e3 + 5;
int n, k, S2[maxn][maxn], fac[maxn], ifac[maxn];
int C(int n, int m) {return mul(fac[n], mul(ifac[m], ifac[n - m]));}
int main() {
    scanf("%d%d", &n, &k);
    S2[1][1] = 1;
    for (int i = 2; i <= n + 1; i++)
    for (int j = 1; j <= i; j++)
        S2[i][j] = add(S2[i - 1][j - 1], mul(S2[i - 1][j], j));
    fac[0] = ifac[0] = 1;
    for (int i = 1; i <= n + 1; i++) {
        fac[i] = mul(fac[i - 1], i);
        ifac[i] = fpow(fac[i], cmd - 2);
    }
    int ans = 0;
    for (int i = k + k; i <= n + 1; i++) {
        int s1 = 0, s2 = 0;
        for (int j = k; j <= i - k; j++)
            s1 = add(s1, mul(S2[j][k], S2[i - j][k]));
        if (i < n + 1) {
            for (int j = 1; j <= n + 1 - i; j++)
                s2 = add(s2, S2[n + 1 - i][j]);
        } else s2 = 1;
        ans = add(ans, mul(s1, mul(s2, C(n + 1, i))));
    }
    printf("%d", ans);
    return 0;
}

标签:return,int,cmd,Subsequence,maxn,Bmatrix,Decreasing,mul,ARC138E
来源: https://www.cnblogs.com/klii/p/16128517.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有