终于讲到反演定理了,反演定理这种东西记一下公式就好了,反正我是证明不出来的~(~o ̄▽ ̄)~o

 

 

 

 

 

 

 

首先,著名的反演公式

我先简单的写一下o( ̄ヘ ̄*o)

比如下面这个公式

f(n) = g(1) + g(2) + g(3) + ... + g(n)

如果你知道g(x),蓝后你就可以知道f(n)了

 

如果我知道f(x),我想求g(n)怎么办

这个时候,就有反演定理了

反演定理可以轻松的把上面的公式变为

g(n) = f(1) + f(2) + f(3) + ... + f(n)

 

当然,我写的只是个形式,怎么可能这么简单。◕‿◕。

 

其实每一项再乘一个未知的函数就对了,但是这个函数我们不知道(不用担心,数学家已经帮我们解决了,我们直接用就可以了)

 

 

 

 

 

 

反演公式登场( >ω<)

 

数论17——反演定理(二项式反演)

 

c和d是两个跟n和r有关的函数

根据用法不同,c和d是不同的

一般数学家会先随便弄c函数

然后经过复杂的计算和证明,得到d函数

然后公式就可以套用了

 

 

 

 

 

 

 

 

 

 

 

正片开始

 

二项式反演公式

 

数论17——反演定理(二项式反演)

 

那个括号起来的就是组合数,我记得组合数那章我有说过

数论17——反演定理(二项式反演)

 

 

二项式反演也就是记住这个公式就算结束了

 

然后我们开始实战(/ω\)

 

 

 

 

 

 

 

 

 

容斥那章讲过的全错排(装错信封问题)

hdu 1465

http://acm.hdu.edu.cn/showproblem.php?pid=1465

 

 

 

 设g(i)表示正好有i封信装错信封

那么全部的C(n, i)*g(i)加起来正好就是所有装信的情况,总共n!种情况

n! = Σ C(n, i)*g(i) (i从0到n)

那么f(n) = n!,所以f(x) = x!

那么我们要求g(n)

根据公式

 

g(n) = Σ (-1)^(n-i) * C(n, i) * f(i)  (i从0到n)

 

那么就可以计算啦~\(≧▽≦)/~

 

AC代码:

#include<cstdio>
typedef long long LL;
int n, flag;
LL fac[25];
LL ans;
void init(){
    fac[0] = 1;
    for(int i = 1; i <= 20; i ++) fac[i] = fac[i-1] * i;    
}
int main(){
    init();
    while(~scanf("%d", &n)){
        ans = 0;
        flag = n & 1 ? -1 : 1;//起始符号
        for(int i = 0; i <= n; i ++){
            ans += flag * fac[n] / fac[n-i];
            flag = -flag;  
        }
        printf("%I64d\n", ans);
    }
}
View Code

相关文章:

猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-06-11
相关资源
相似解决方案