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

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

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

反演公式登场( >ω<)

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

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

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

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

然后公式就可以套用了

正片开始

二项式反演公式

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

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

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

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

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

是不是很好用但是不容易想到T_T

这也没有办法

再来一题吧

还是容斥那一章讲过的题目的

UVALive 7040

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5052

题意:给n盆花涂色,从m种颜色中选取k种颜色涂,保证正好用上k种颜色,你必须用上这k种颜色去涂满n个相邻的花,并且要求相邻花的颜色不同,求方案数。

(1 ≤ n, m ≤ 1e9 , 1 ≤ k ≤ 1e6 , k ≤ n, m)

首先,用k种颜色涂花,假如不考虑全部用上,那么总的方案数是多少

第一盆花有k种颜色选择,之后的花因为不能跟前一盆花的颜色相同,所以有k-1种选择

于是总方案数为k*(k-1)^(n-1)

我们设必须用 i 种颜色两两不相邻的涂花的方案数为 g(i)

那么

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

令f(k) = k*(k-1)^(n-1),那么f(x) = x*(x-1)^(n-1)

二项式反演公式出现了

所以g(k) = Σ (-1)^(k-i) * C(k, i) * f(i)  (i从1到k)

最终的答案就是C(m, k) * g(k)

(这里m有1e9,C(m, k)直接用for循环算,直接for循环从m*(m-1)*...*(m-k+1)再乘k的阶乘的逆元)

AC代码:

 1 #include<cstdio>
 2 typedef long long LL;
 3 const int N = 1000000 + 5;
 4 const int MOD = (int)1e9 + 7;
 5 int F[N], Finv[N], inv[N];
 6 LL pow_mod(LL a, LL b, LL p){
 7     LL ret = 1;
 8     while(b){
 9         if(b & 1) ret = (ret * a) % p;
10         a = (a * a) % p;
11         b >>= 1;
12     }
13     return ret;
14 }
15 void init(){
16     inv[1] = 1;
17     for(int i = 2; i < N; i ++){
18         inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
19     }
20     F[0] = Finv[0] = 1;
21     for(int i = 1; i < N; i ++){
22         F[i] = F[i-1] * 1ll * i % MOD;
23         Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD;
24     }
25 }
26 int comb(int n, int m){
27     if(m < 0 || m > n) return 0;
28     return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD;
29 }
30 int main(){
31     init();
32     int T, n, m, k, ans, flag, temp;
33     scanf("%d", &T);
34     for(int cas = 1; cas <= T; cas ++){
35         scanf("%d%d%d", &n, &m, &k);
36         ans = 0;
37         flag = (k & 1) ? 1 : -1;
38         //计算g(k)
39         for(int i = 1; i <= k; i ++){
40             ans = (ans + 1ll * flag * comb(k, i) * i % MOD * pow_mod(i-1, n-1, MOD) % MOD) % MOD;
41             flag = -flag;
42         }
43         //接下来计算C(m, k)
44         temp = Finv[k];
45         for(int i = 1; i <= k; i ++){
46             temp = 1ll * temp * (m-k+i) % MOD;
47         }
48         ans = ((1ll * ans * temp) % MOD + MOD) % MOD;
49         printf("Case #%d: %d\n", cas, ans);
50     }
51 }

View Code

做完两题之后就感觉二项式反演变得容易了,遇到题目还是要多想( ̄▽ ̄")

等等。。。做完两题的我突然发现二项式反演和容斥推倒出来的公式总是一样的。。。。。。(为什么有种被骗的感觉T_T)

转载于:https://www.cnblogs.com/linyujun/p/5210650.html

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

  1. ACM数论之旅4---扩展欧几里德算法(欧几里德(・∀・)?是谁?)

    为什么老是碰上 扩展欧几里德算法 ( •̀∀•́ )最讨厌数论了 看来是时候学一学了 度娘百科说: 首先, ax+by = gcd(a, b) 这个公式肯定有解 (( •̀∀•́ )她说根据数论中的相 ...

  2. ACM数论之旅2---快速幂,快速求a^b

    如果题目说数据很大,还需要求余,那么代码就可以这么写 LL pow_mod(LL a, LL b){//a的b次方LL ret = 1;while(b != 0){if(b % 2 == 1){ret ...

  3. ACM数论之旅3---最大公约数gcd和最小公倍数lcm(苦海无边,回头是岸( ̄∀ ̄))...

    gcd(a, b),就是求a和b的最大公约数 lcm(a, b),就是求a和b的最小公倍数 然后有个公式 a*b = gcd * lcm     ( gcd就是gcd(a, b), ( •̀∀•́ ) ...

  4. 【C++探索之旅】开宗明义+第一部分第一课:什么是C++?

    内容简介 1.课程大纲 2.第一部分第一课:什么是C++? 3.第一部分第二课预告:C++编程的必要软件 开宗明义 亲爱的读者,您是否对C++感兴趣,但是C++看起来很难,或者别人对你说C++挺难的, ...

  5. 小猪的Python学习之旅 —— 17.Python数据分析:我主良缘交友了解下

    小猪的Python学习之旅 -- 17.Python数据分析:我主良缘交友了解下 标签:Python 一句话概括本文: 爬取我主良缘交友所有的妹子信息,利用Jupyter Notebook对五个方面: ...

  6. ACM数论专题3——素数(质数)

    ACM数论专题3--素数 素数是什么 蛮力算法求素数 蛮力算法的实现以及分析 时间复杂度 蛮力算法的改进 时间复杂度 **埃筛** 时间复杂度 线筛 线筛原理分析 线筛实现 素数是什么 质数1 (pr ...

  7. [你必须知道的css系列]第一回:丰富的利器2:CSS选择符之子选择符、相邻选择符...

    对了,接下来要讲的属性选择符,相邻选择符,子对象选择符可能大家稍微有点陌生了,这当然也是有原因的,因为IE6及以下的浏览器并不支持这几个选择符,而 大多数从事这方面工作的技术人员,多数时候还是主要考虑 ...

  8. 读书:儒林外史第一回

    第一回讲了王冕的人生经历. 王冕家境贫穷,但聪颖好学,也很会学习.他自学三个月的画画,就能画一幅好画,还能够卖出去.会作诗,诗集也能卖出去.这种人才搁到现在,估计也早实现财务自由. 王冕不是死读书的人 ...

  9. [Sharepoint2007对象模型]第一回:服务器场(SPFarm)

    Sharepoint是微软一个很重要的服务器产品,它可以方便的创建和维护一个网站,在Sharepoint的管理中心提供了很强大的管理工具.同时为了更加灵活的后期定制和开发,Sharepoint提供了完 ...

最新文章

  1. 【地图API】收货地址详解2
  2. ASP.NET ASHX中获得Session
  3. 系统模块——什么是系统模块、path 路径操作、相对路径VS绝对路径
  4. LeetCode215:数组中第K个最大元素
  5. mysql死锁释放时间参数_由FTWRL导致的MySQL从库死锁分析及参数深究
  6. 数据库连接池_DataSource_数据源(简单介绍C3P0和Druid)
  7. Git相关命令及用法
  8. 《Cortex-M0权威指南》之体系结构---系统模型
  9. BG.Hive - part3
  10. 使用jQuery实现网页技术(无数据库)
  11. mike21 matlab tools,Mike post process with Matlab toolbox
  12. 数据库优化相关面试题
  13. 固定资产管理系统对企业的意义?
  14. oracle磁带库清洁带标签,LTO-1/2/3/4/5/6/7/8 Ultrium数据磁带 清洗带 清洁带 磁带标签批发...
  15. SpringCloud基础学习
  16. 电子签名就是数字签名吗?
  17. 配置openldap使用SSL连接
  18. 一文看懂语音技术商业化逻辑:对品牌意味着什么 | 综述
  19. hive谓词与cbo的一些奇葩事
  20. 三光(可见光、红外光、激光)云台产品调研

热门文章

  1. 10 分钟入门 AST 代码优化与修改
  2. access数据库删除两个日期之间 的数据 SQL语句
  3. 国际域名转出ICANN投诉
  4. [Flash开发笔记] 关于Flash中的ASO文件
  5. html如何打包压缩,所有css打包压缩到一个js里面
  6. Windows下Anaconda2(Python2)和Anaconda3(Python3)的共存
  7. pip在windows下安装配件/宏包
  8. 史上最大的实体关系抽取数据集!清华大学自然语言处理团队发布 FewRel...
  9. Blink Coordinate Spaces
  10. 11.15日工作总结(补)