zoukankan      html  css  js  c++  java
  • cojs QAQ的图论题 题解报告

    话说这个题目应该叫做 斯特林数的逆袭 QAQ

    先说一说部分分的算法

    1、n<=5 直接暴力搜索就可以了

    2、k=0的时候不难发现任意一张图的价值都是n,问题转化为计算有多少种图,显然是2^C(n,2)

    3、k=1的时候不难发现任意一张图的价值都是其度数的和,暴力1->10的n不难发现规律QAQ

    4、实际上3的算法的规律会启发我们想到这个算法,不难发现每个点的度数的贡献都是独立的

    不妨每一个点度数恰好为i的方案数并且计算贡献就可以了QAQ

    当前点度数为i,则显然他要向i个点连边,可连边的点一共有(n-1)个

    其余(n-1)个点之间随意连边

    不难得到贡献为C(n-1,i)*i^k*2^C(n-1,2)

    然后考虑每个点实际上都是等价的,可以得到ans=sigma(C(n-1,i)*i^k)*n*2^C(n-1,2)

    然后预处理阶乘和阶乘的逆元,可以在O(n)时间内计算答案

    这样加起来就有50分辣

    5、我们考虑这个式子是否可以化简

    注意到i^k=sigma(S(k,j)*j!*C(i,j))

    从组合数学的角度理解就是i^k实际上是在i个数中可重选取k个数的方案

    我们考虑选取的这k个数都是哪些数,不妨枚举j

    那么把k个数分给j个集合就是第二类斯特林数,集合有序所以乘以j!

    最后乘以在i个数中选取j个数的方案C(i,j)就可以得到这个式子

    之后展开式子,把C(n-1,i)和C(i,j)*j!合并可以得到

    ans=sigma((S(k,j)*(n-1)*(n-2)……*(n-j)*sigma(C(n-j-1,i-j))*n*2^C(n-1,2)

    不难发现sigma(C(n-j-1,i-j))=2^(n-j-1)

    所以计算这个式子我们只需要枚举j就可以了,我们会惊奇的发现这样时间复杂度是O(k)的

    然后暴力计算斯特林数的时间复杂度是O(k^2)

    总时间复杂度O(k^2),这样结合前面的算法就有70分了

    6、考虑时间复杂度的瓶颈在于计算斯特林数

    而我们实际上只是求第k行的斯特林数就可以了

    我们知道斯特林数的通项公式是

    S(n,m)=1/m!*sigma((-1)^k*C(m,k)*(m-k)^n)

    从容斥的角度解释的话我们会发现我们有m个盒子,n个元素

    可以有空盒的方案实际上是m^n

    考虑到条件是不可以有空盒所以我们可以利用容斥原理

    枚举至少有k个空盒,其余的盒子任意装,方案为C(m,k)*(m-k)^n

    然后套上容斥系数就可以了,注意这里的盒子是无序的,所以我们最后还要消序QAQ

    不难发现这个式子是一个卷积形式,我们利用这个式子构造多项式并做FFT

    就可以在O(klogk)的时间内求出第k行的所有斯特林数了

    时间复杂度O(klogk) QAQ 这样我们就圆满的解决这道题目了

  • 相关阅读:
    利用Python进行数据分析笔记-时间序列(时区、周期、频率)
    形象易懂讲解算法I——小波变换
    小波变换与傅里叶变换的区别
    Thinkpad E550 开启 Legacy Only
    Thinkpad E550 开启 虚拟化
    常见音频接口
    IAR embedded Workbench for ARM 8.32.1 安装包
    stm32f767 无操作系统 LwIP 移植 (一)
    stm32f767 无操作系统 LwIP 移植 (二)
    北京市电力公司
  • 原文地址:https://www.cnblogs.com/joyouth/p/5599564.html
Copyright © 2011-2022 走看看