zoukankan      html  css  js  c++  java
  • 容斥原理初探

    前言

    确实是初探,因为以前学得太烂了。。。

    参考了这篇日报: https://www.luogu.com.cn/blog/KingSann/chu-tan-rong-chi-yuan-li

    下面的(U)是全集,(|S|)表示集合(S)的大小。

    正常项的容斥原理

    大概长成这个样子吧:

    [|S_1cup S_2cup ...cup S_m|=sum_{Tsubseteq U}(-1)^{|T|+1}|S_{T1}cap S_{T2}cap ...| ]

    一般化的容斥原理

    下面的答案可以指任意答案。

    我们假设存在以下函数:

    1. (q(S)),表示至少包含属性集合(S)的集合个数

    2. (g(n)),表示属性集合大小为(n)的集合对答案产生的贡献

    3. (f(i)),表示容斥系数

    我们需要我们的(f(i))满足答案为(sum_{Ssubseteq U} q(S)f(|S|))

    那么,我们考虑一个大小为(n)的集合对答案产生的贡献,显然它满足:

    [sum_{i=1}^{n}inom{n}{i}f(i)=g(n) ]

    这个式子非常显然。

    于是,我们就可以推得:

    [f(n)=g(n)-sum_{i=1}^{n-1}inom{n}{i}f(i) ]

    我们就可以递推求得(f(x))。不过这里有一种更快的方法。我们下面假设(F(x))(f(x))的指数型生成函数(定义(f(0)=0)),(G(x))(g(x))的指数型生成函数,可以发现:

    [F(x)e^x=G(x) ]

    [Rightarrow F(x)=e^{-x}G(x) ]

    而我们的(e^{-x})又是(sum_{i=1}^{infty} (-1)^idfrac{x^i}{i!}),于是我们就可以直接多项式乘法做到(Theta(nlog n))

    我们其实还可以使用二项式反演求到:

    [f(n)=sum_{i=0}^{n}(-1)^{n-i}inom{n}{i}g(i) ]

    一些小小的应用

    正常项容斥原理的证明

    显然,这里的答案就是至少出现过一次的元素个数,属性集合就是一个元素在哪些集合里面出现过,(g(n)=[nge 1]),于是根据上面的上面的式子求得(f(n)=(-1)^{n+1}),于是我们得证了。

    错排问题

    显然,这里的答案就是错排个数,属性集合就表示的是哪些位置对应数相同,(g(n))就是([n=0])。于是,我们发现如果我们取(f(x)=(-1)^x)的话,就可以满足:

    [sum_{i=1}^{n} inom{n}{i}f(i)=g(n) ]

    这个可以使用二项式定理证明。

    于是我们的答案就是:

    [sum_{i=0}^{n}(-1)^i inom{n}{i}(n-i)! ]

    [=sum_{i=0}^{n} (-1)^i dfrac{n!}{i!} ]

    [=n!sum_{i=0}^{n} dfrac{(-1)^i}{i!} ]

    然后如果我们设(f(n))(n)个点的错排个数的话,根据上面的式子就可以得到一个递推式:

    [f(n)=(-1)^n+nf(n-1) ]

    当然还有考虑组合意义的递推公式,但是与主题无关,所以这里就不讲了。

  • 相关阅读:
    ubuntu 安装QT 5.0出现错误:Failed to load platform plugin "xcb".
    Ubuntu手动编译GCC
    C++面试题集锦(一)
    C++排序系列(一) 插入排序之折半插入排序
    关于内存对齐的面试题
    C++中的static_cast, dynamic_cast和reinterpret_cast
    C++排序系列(二) 交换排序之简单排序
    Cannot open include file: 'iphlpapi.h': No such file or directory(最终解决方法)
    C++排序系列(一) 插入排序之直接插入排序
    ubuntu aptget update时出现W: GPG 错误
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/13404581.html
Copyright © 2011-2022 走看看