二项式反演[bzoj3622]已经没有什么好害怕的了
前言
继续学习容斥的技巧!
题意简介
题面链接
题目大意
给出两个数组a,ba,ba,b
求有多少种对应方式使得有恰好kkk对匹配(i,j)(i,j)(i,j)满足ai>bja_i>b_jai>bj
数据范围
n≤2000,0≤k≤nn\le2000,0\le k\le nn≤2000,0≤k≤n
题解
部分分
这道题的暴力是指数级的,对于这样的数据范围显得非常没有意义
正解
发现暴力的瓶颈在于枚举匹配的集合,那么说明我们不能直接枚举集合
考虑减少限制,使得计算变得简单,然后再把不满足的都扔掉,那么就能做出这道题,也就是容斥
我们先将两个数组分别排序,这样的话容易发现对于aaa中的一个元素aia_iai,满足ai>bja_i>b_jai>bj的bjb_jbj是bbb的一个前缀
定义g[i]g[i]g[i]为最大的下标jjj满足bj<aib_j<a_ibj<ai
定义f[i][j]f[i][j]f[i][j]表示aaa数组的前iii个数,其中确定有jjj对匹配满足a>ba>ba>b(确定那么多,但不代表只有那么多),在这样的情况下这jjj对的选择方案数(这jjj对以外的数的匹配不同算同一种方案)
然后很容易贴出转移式子f[i][j+1]=f[i−1][j+1]+f[i−1][j]∗(g[i]−j)f[i][j+1]=f[i-1][j+1]+f[i-1][j]*(g[i]-j)f[i][j+1]=f[i−1][j+1]+f[i−1][j]∗(g[i]−j)
第一项代表当前这个数不匹配,第二项表示当前这个数匹配
设F[i]=f[n][i]∗(n−i)!F[i]=f[n][i]*(n-i)!F[i]=f[n][i]∗(n−i)!,那么F[i]F[i]F[i]就表示满足a>ba>ba>b的匹配对数大于等于jjj的对应方式数(注意,这个定义和上面的不同,乘一个阶乘后就所有数都固定了)
定义Ans[i]Ans[i]Ans[i]表示满足a>ba>ba>b的匹配对数等于jjj的对应方式数
容易发现Ans[k]Ans[k]Ans[k]即我们所要的答案
我们发现这样一个显然的式子F[k]=∑i=kn(ik)Ans[i]F[k]=\sum_{i=k}^n\binom{i}{k}Ans[i]F[k]=i=k∑n(ki)Ans[i]
注:(ij)=C(i,j)\binom{i}{j}=C(i,j)(ji)=C(i,j)即组合数
二项式反演即可得Ans[k]=∑i=kn(−1)i−k(ik)F[i]Ans[k]=\sum_{i=k}^n(-1)^{i-k}\binom{i}{k}F[i]Ans[k]=i=k∑n(−1)i−k(ki)F[i]
那么什么是二项式反演呢?请看下一节
我们先把这题讲完,假设你推出了这个,那么就可以直接算答案了
前面dpdpdp的复杂度是Θ(n2)\Theta(n^2)Θ(n2)的,后面的答案计算由于只要算一个所以是Θ(n)\Theta(n)Θ(n)的
综上,总复杂度Θ(n2)\Theta(n^2)Θ(n2)
二项式反演
二项式反演的经典形式为fn=∑i=0n(−1)i(ni)gi⇔gn=∑i=0n(−1)i(ni)fif_n=\sum_{i=0}^n(-1)^i\binom{n}{i}g_i\Leftrightarrow g_n=\sum_{i=0}^n(-1)^i\binom{n}{i}f_ifn=i=0∑n(−1)i(in)gi⇔gn=i=0∑n(−1)i(in)fi
这篇博客用到的式子是另一个经典模型
fi=∑j=0i(n−jn−i)gj⇔gi=∑j=0i(−1)i−j(n−jn−i)fjf_i=\sum_{j=0}^i\binom{n-j}{n-i}g_j\Leftrightarrow g_i=\sum_{j=0}^i(-1)^{i-j}\binom{n-j}{n-i}f_jfi=j=0∑i(n−in−j)gj⇔gi=j=0∑i(−1)i−j(n−in−j)fj
应用的时候其实是进行了数组翻转和特殊值代换产生的
要问证明?请看我的另一篇总结博客
代码
东西讲完了,就可以安心写出前面的那一题了,贴上ac代码
#include<cstdio>
#include<cctype>
#include<algorithm>
namespace fast_IO
{const int IN_LEN=10000000,OUT_LEN=10000000;char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1;inline char getchar_(){return (ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,1,IN_LEN,stdin),ih==lastin)?EOF:*ih++;}inline void putchar_(const char x){if(oh==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf;*oh++=x;}inline void flush(){fwrite(obuf,1,oh-obuf,stdout);}
}
using namespace fast_IO;
#define getchar() getchar_()
#define putchar(x) putchar_((x))
#define rg register
typedef long long LL;
template <typename T> inline T max(const T a,const T b){return a>b?a:b;}
template <typename T> inline T min(const T a,const T b){return a<b?a:b;}
template <typename T> inline void mind(T&a,const T b){a=a<b?a:b;}
template <typename T> inline void maxd(T&a,const T b){a=a>b?a:b;}
template <typename T> inline T abs(const T a){return a>0?a:-a;}
template <typename T> inline void swap(T&a,T&b){T c=a;a=b;b=c;}
template <typename T> inline T gcd(const T a,const T b){if(!b)return a;return gcd(b,a%b);}
template <typename T> inline T lcm(const T a,const T b){return a/gcd(a,b)*b;}
template <typename T> inline T square(const T x){return x*x;};
template <typename T> inline void read(T&x)
{char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;
}
template <typename T> inline void printe(const T x)
{if(x>=10)printe(x/10);putchar(x%10+'0');
}
template <typename T> inline void print(const T x)
{if(x<0)putchar('-'),printe(-x);else printe(x);
}
const LL mod=1000000009;
inline void md(LL&x){if(x>=mod)x-=mod;}
int n,k;
int a[2001],b[2001],g[2001];
inline LL pow(LL x,LL y)
{LL res=1;for(;y;y>>=1,x=x*x%mod)if(y&1)res=res*x%mod;return res;
}
LL fac[2001],inv[2001];
inline LL C(const LL x,const LL y)
{return fac[x]*inv[y]%mod*inv[x-y]%mod;}
LL f[2001],ans;
int main()
{read(n),read(k);if((n&1)!=(k&1)){print(0);return flush(),0;}k=(n-k)/2+k;for(rg int i=1;i<=n;i++)read(a[i]);for(rg int i=1;i<=n;i++)read(b[i]);std::sort(a+1,a+n+1);std::sort(b+1,b+n+1);for(rg int i=1,j=0;i<=n;i++){while(j<n&&b[j+1]<a[i])j++;g[i]=j;}fac[0]=1;for(rg int i=1;i<=n;i++)fac[i]=fac[i-1]*i%mod;inv[n]=pow(fac[n],mod-2);for(rg int i=n;i>=1;i--)inv[i-1]=inv[i]*i%mod;f[0]=1;for(rg int i=1;i<=n;i++)for(rg int j=n-1;j>=0;j--)md(f[j+1]+=f[j]*(g[i]-j)%mod);for(rg int i=k,j=1;i<=n;i++,j^=1){if(j)ans+=f[i]*C(i,k)%mod*fac[n-i]%mod;else ans-=f[i]*C(i,k)%mod*fac[n-i]%mod;}ans%=mod,ans+=mod,ans%=mod;print(ans);return flush(),0;
}
总结
二项式反演还是挺有效的,也很好用,继续学习!
二项式反演[bzoj3622]已经没有什么好害怕的了相关推荐
- 二项式反演(学习笔记)
q w q qwq qwq机房最后一个学二项式反演的人 众所周知 二项式反演可以表示成 f n = ∑ i = 0 n ( − 1 ) i × C n i × g i ⟺ g n = ∑ i = 0 ...
- 二项式反演(非详细)
引入 二项式反演又名广义容斥定理 二项式反演可以表示成: f[n]=∑i=0n(−1)iCnigi⟺gn=∑i=0n(−1)iCnif[i]f[n]=\sum_{i=0}^n(-1)^iC_{n}^{ ...
- 二项式反演(广义容斥定理)学习笔记
背景: 二项式反演又名广义容斥定理. 下次再看题解时要注意了. 解锁新姿势. 说白了就是之前会的姿势太少了. 正题: 说白了就是有这样两条恒等的式子: f n = ∑ i = 0 n ( − 1 ) ...
- ACM数论之旅17---反演定理 第一回 二项式反演(神说要有光 于是就有了光(´・ω・`))...
终于讲到反演定理了,反演定理这种东西记一下公式就好了,反正我是证明不出来的~(-o ̄▽ ̄)-o 首先,著名的反演公式 我先简单的写一下o( ̄ヘ ̄*o) 比如下面这个公式 f(n) = g(1) + g ...
- 集合计数 二项式反演_对计数数据使用负二项式
集合计数 二项式反演 The Negative Binomial distribution is a discrete probability distribution that you should ...
- [2021.1.27多校省选模拟10]染色(min-max容斥/二项式反演)
[2021.1.27多校省选模拟10]染色 突然发现我对概率期望的理解不是很好... 部分分1:可以直接进行状压dp,然后按照题意模拟即可. 部分分2:首先可以发现这个问题是min_max容斥形式,然 ...
- P6295 有标号 DAG 计数(多项式指数函数对数函数/二项式反演/动态规划/生成函数)
P6295 有标号 DAG 计数 https://www.luogu.com.cn/problem/P6295 求解n个点的有标号弱联通DAG个数 首先根据exp的组合意义,我们考虑指数型生成函数,那 ...
- 【UOJ574】多线程计算【二元二项式反演】【定积分】【矩阵】【NTT 卷积】
题意:有 n×mn\times mn×m 的网格,每个结点在 [0,1)[0,1)[0,1) 内的一个随机时刻被点亮.有 hhh 个数对 xi,yix_i,y_ixi,yi,对于一个瞬间状态,如果 ...
- 【LOJ6072】苹果树【折半搜索】【矩阵树定理】【二项式反演】
题意:有好坏两种点共 nnn 个,每个好点有权值,把这 nnn 个点连成一棵树,一个好点为有用的当且仅当它至少与一个好点相邻,求所有有用的点的权值和不超过 limlimlim 的方案数. n≤40n\ ...
最新文章
- 敏捷开发一千零一问系列之四:优先级排错怎么办?
- 用createinstallmedia创建可恢复的OSX安装DMG
- Python课堂:判定IP地址合法性的三种方法
- 新装WINDOWS XP系统 必须安装的十大高危漏洞补丁
- Javascript获取屏幕与页面尺寸
- CPython对象模型:整型
- Hibernate Tomcat JNDI DataSource示例教程
- arcgis 删除图形重复折点_【干货】ArcGIS中画环状图斑、挑子区及消除图斑重复区域...
- QT出现 Cannot create children for a parent that is in a different thread 的解决方法:
- 框架学习 Spring之概念
- Mysql备份策略-完成备份+增量备份shell
- 不能忽视的情绪 -- 喜怒哀惧,也不过度关注
- excel熵值法计算权重_由搜索权重排序引入的思考
- 小程序之模版消息通知
- PyCharm大学生教育账户激活
- EMC与电阻、电容和电感的关系
- Excel条件格式使用小总结
- 哈希表 matlab实现,MATLAB中的哈希表
- 清北学堂 2017-10-05
- 【二分】C. Keshi Is Throwing a Party