zoukankan      html  css  js  c++  java
  • AGC024E Sequence Growing Hard

    Link
    (A_i)相比于(A_{i-1})只多了一个元素,保证新加入的元素放在一个不大于它的元素的前面即可。
    但是这样会算重,让新加入的元素放在一个小于它的元素前面即可去重。
    为了方便我们认为(A_0={0})
    在第(i)次操作中,如果我们把新加入的元素放在第(j)次操作加入的元素的左边,那么我们就认为(j)(i)的父亲。
    那么我们可以得到一棵(n+1)个点的数,树上的点有([0,n])的标号,且每个点都有一个([0,k])之间的权值,而这棵树满足以标号/权值来看都是一个严格小根堆。
    可以发现满足以标号/权值来看都是一个严格小根堆的树与操作方案一一对应。
    (f_{i,j})表示有(i)个点,标号为([0,i)),根节点权值为(j)的合法的树的个数。
    很显然此时(0)为根节点,转移枚举(1)号点(标号最小的儿子)的权值与子树大小即可。
    (f_{i,j}=sumlimits_{v=j+1}^ksumlimits_{l=1}^{i-1}f_{i-l,j}f_{l,v}{i-2choose l-1})
    (s_{i,j}=sumlimits_{l=j}^kf_{i,l})后缀和优化即可。

    #include<cstdio>
    const int N=307;
    int P,C[N][N],f[N][N],s[N][N];
    void inc(int&a,int b){a+=b-P,a+=a>>31&P;}
    void dec(int&a,int b){a-=b,a+=a>>31&P;}
    int main()
    {
        int n,k;scanf("%d%d%d",&n,&k,&P);
        for(int i=0;i<=n;++i) for(int j=C[i][0]=1;j<=i;++j) inc(C[i][j]=C[i-1][j],C[i-1][j-1]);
        for(int i=0;i<=k;++i) f[1][i]=1,s[1][i]=k-i+1;
        for(int i=2;i<=n+1;++i)
        {
    	for(int j=0;j<=k;++j) for(int l=1;l<i;++l) inc(f[i][j],1ll*f[i-l][j]*s[l][j+1]%P*C[i-2][l-1]%P);
    	for(int j=k;j;--j) inc(s[i][j]=s[i][j+1],f[i][j]);
        }
        printf("%d",f[n+1][0]);
    }
    
  • 相关阅读:
    算法设计和分析(Prim算法构建最小生成树)
    寒假第二阶段集训第6天
    2.4 综合训练
    1月18日 LCA专项训练
    易班易喵喵话题动态自动统计
    P2590 [ZJOI2008]树的统计
    P3038 [USACO11DEC]牧草种植Grass Planting
    2157: 旅游
    P2787 语文1(chin1)- 理理思维
    F. Make Them Similar
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12699273.html
Copyright © 2011-2022 走看看