• 洛谷P5853 [USACO19DEC] Tree Depth P


    (f_{n,k}) 为逆序对为 (k)(n) 阶排序数量,其生成函数为 (F_n(x)=sumlimits_{kgeqslant 0} f_{n,k} x^k),考虑排列的第 (i) 个位置,通过决定其与前 (i-1) 个位置的相对大小,得其对逆序对的贡献范围为 ([0,i-1]),因此有:

    [large F_n(x)=prod_{i=1}^nsum_{j=0}^{i-1}x^j=prod_{i=1}^nfrac{1-x^i}{1-x} ]

    节点深度转化为有多少个节点为该节点的祖先,得 (j)(i) 在笛卡尔树上的祖先的充要条件是 (p_j) 是区间 ([min(i,j),max(i,j)]) 的最小值。考虑刚才构造排列的方法,从 (i) 开始向 (j) 的方向或反方向,决定每个位置的相对大小,得 (j<i) 时,(j) 不产生逆序对,(j>i) 时,(j) 产生 (j-i) 个逆序对。每次先让 (i) 位置对逆序对的贡献在区间 ([0,i-1]) 内,然后枚举 (j),撤销掉贡献即可。

    #include<bits/stdc++.h>
    #define maxn 50010
    using namespace std;
    template<typename T> inline void read(T &x)
    {
        x=0;char c=getchar();bool flag=false;
        while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        if(flag)x=-x;
    }
    int n,k,p,m;
    int f[maxn],g[maxn];
    int main()
    {
        read(n),read(k),read(p),m=n*(n-1)/2,f[0]=1;
        for(int i=1;i<=n;++i)
        {
            for(int j=m;j>=i;--j) f[j]=(f[j]-f[j-i]+p)%p;
            for(int j=1;j<=m;++j) f[j]=(f[j]+f[j-1])%p;
        }
        for(int i=1;i<=n;++i) g[i]=f[k];
        for(int i=2;i<=n;++i)
        {
            for(int j=m;j;--j) f[j]=(f[j]-f[j-1]+p)%p;
            for(int j=i;j<=m;++j) f[j]=(f[j]+f[j-i])%p;
            for(int j=1;j+i-1<=n;++j)
            {
                if(k-i+1>=0) g[j]=(g[j]+f[k-i+1])%p;
                g[j+i-1]=(g[j+i-1]+f[k])%p;
            }
            for(int j=m;j>=i;--j) f[j]=(f[j]-f[j-i]+p)%p;
            for(int j=1;j<=m;++j) f[j]=(f[j]+f[j-1])%p;
        }
        for(int i=1;i<=n;++i) printf("%d ",g[i]);
        return 0;
    }
    
  • 相关阅读:
    .net 设置默认首页
    MySQL如何对数据库状态值指定排序
    golang将mm-dd-yy的字符串转时间格式
    Nginx文件解析
    Git使用笔记
    批量导入实现逻辑
    golang字符串截取
    golang格式化代码
    golang获取某一年某一月份的开始日期和结束日期
    nslookup install
  • 原文地址:https://www.cnblogs.com/lhm-/p/13823623.html
Copyright © 2020-2023  润新知