终于讲到反演定理了,反演定理这种东西记一下公式就好了,反正我是证明不出来的~(~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)

 

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

 

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

 

 

 

 

 

 

反演公式登场( >ω<)

 

ACM数论之旅17---反演定理 第一回 二项式反演(神说要有光 于是就有了光(´・ω・`))

 

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

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

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

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

然后公式就可以套用了

 

 

 

 

 

 

 

 

 

 

 

正片开始

 

二项式反演公式

 

ACM数论之旅17---反演定理 第一回 二项式反演(神说要有光 于是就有了光(´・ω・`))

 

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

ACM数论之旅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代码:

 1 #include<cstdio>
 2 typedef long long LL;
 3 int n, flag;
 4 LL fac[25];
 5 LL ans;
 6 void init(){
 7     fac[0] = 1;
 8     for(int i = 1; i <= 20; i ++) fac[i] = fac[i-1] * i;    
 9 }
10 int main(){
11     init();
12     while(~scanf("%d", &n)){
13         ans = 0;
14         flag = n & 1 ? -1 : 1;//起始符号
15         for(int i = 0; i <= n; i ++){
16             ans += flag * fac[n] / fac[n-i];
17             flag = -flag;  
18         }
19         printf("%I64d\n", ans);
20     }
21 }
View Code

相关文章: