cf111D Petya and Coloring 组合数学,二项式反演
http://codeforces.com/contest/111/problem/D
Little Petya loves counting. He wants to count the number of ways to paint a rectangular checkered board of size n × m (n rows, m columns) in k colors. Besides, the coloring should have the following property: for any vertical line that passes along the grid lines and divides the board in two non-empty parts the number of distinct colors in both these parts should be the same. Help Petya to count these colorings.
The first line contains space-separated integers n, m and k (1 ≤ n, m ≤ 1000, 1 ≤ k ≤ 106) — the board's vertical and horizontal sizes and the number of colors respectively.
Print the answer to the problem. As the answer can be quite a large number, you should print it modulo 109 + 7 (1000000007).
2 2 1
1
2 2 2
8
3 2 2
40 题意:
给出一个 n*m 的矩阵,用sum种颜色染色
满足:任意一条竖直线(纵线)把矩阵划分成的2个部分,2个部分的不同的颜色数相同
求方案数
n,m <= 10^3,sum <= 10^6 solution:
注意到n,m的范围不大 显然有以下性质:
1.第1列和第m列的颜色数一定相等
2.2~m-1列的颜色只能从1,m列的颜色的交集中选择 m=1的时候,特殊处理,ans=k^n
m>1的时候,我们只需要考虑1,m列的颜色选择还有交集大小 预处理g[i]表示恰好用i种颜色涂满n个格子的方案数
(此时n是一个常量) 如果用递推式,求g[i]需要O(n^2),求g数组需要O(n^3),tle
考虑二项式反演求g数组:
设h(i)表示用i种颜色染n个格子的方案数,则h(i) = i^n
g(i)表示恰好用i种颜色染n个格子的方案数,
有:h(y) = sigma(i=0,i<=y)(C(y,i)*g(i))
则:g(y) = sigma(i=0,i<=y)((-1)^(y-i) * C(y,i) * h(i))
= sigma(i=0,i<=y)((-1)^(y-i) * C(y,i) * i^n) 这样求g[i]需要O(nlogn),求g数组需要O(n^2*logn)
当然也可以优化到O(n^2)求g数组 主要的预处理部分搞定了,然后就是答案了
退下公式,得到:
ans = sigma(j=0,j<=min(n,sum))C(sum,j) * j^(m*n-2*n) *
(sigma(i=0,i<=min(n-j,(sum-j)/2))(C(sum-j,i)*C(sum-j-i,i)*g(i+j)^2))
//File Name: cf111D.cpp
//Author: long
//Mail: 736726758@qq.com
//Created Time: 2016年05月16日 星期一 01时13分24秒 #include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <math.h> #define LL long long using namespace std; const int MAXN = + ;
const int MAXM = + ;
const int MOD = (int)1e9 + ; LL jie[MAXM];
LL g[MAXN]; LL qp(LL x,LL y){
LL res = ;
while(y){
if(y & ) res = res * x % MOD;
x = x * x % MOD;
y >>= ;
}
return res;
} LL get_c(LL x,LL y){
if(x < y) return ;
if(x == y || y == ) return ;
return jie[x] * qp(jie[y] * jie[x - y] % MOD,MOD - ) % MOD;
} void init(int sum,int n){
jie[] = ;
for(int i=;i<MAXM;i++)
jie[i] = jie[i-] * i % MOD;
int ma = min(sum,n);
LL now;
for(int i=;i<=ma;i++){
for(int k=;k<=i;k++){
now = get_c(i,k) * qp(k,n) % MOD;
if((i - k) % )
g[i] = (g[i] - now + MOD) % MOD;
else
g[i] = (g[i] + now) % MOD;
}
}
} LL solve(int n,int m,int sum){
if(m == ) return qp(sum,n);
init(sum,n);
LL ans = ,now,tmp;
int ma = min(sum,n);
for(int j=,ma2;j<=ma;j++){
now = ;
ma2 = min(n - j,(sum - j) / );
for(int i=;i<=ma2;i++){
(now += jie[sum-j] * qp(jie[sum-j-*i]*jie[i]%MOD*jie[i]%MOD,MOD - ) % MOD
* g[i+j] % MOD * g[i+j] % MOD) %= MOD;
}
tmp = qp(j,(m - ) * n) % MOD;
(ans += get_c(sum,j) * tmp % MOD * now % MOD) %= MOD;
//cout << j << " " <<ans << endl;
}
return ans;
} int main(){
int n,m,k;
scanf("%d %d %d",&n,&m,&k);
printf("%d\n",(int)solve(n,m,k));
return ;
}
cf111D Petya and Coloring 组合数学,二项式反演的更多相关文章
- 洛谷 P5400 - [CTS2019]随机立方体(组合数学+二项式反演)
洛谷题面传送门 二项式反演好题. 首先看到"恰好 \(k\) 个极大值点",我们可以套路地想到二项式反演,具体来说我们记 \(f_i\) 为钦定 \(i\) 个点为极大值点的方案数 ...
- [LOJ3119][CTS2019|CTSC2019]随机立方体:组合数学+二项式反演
分析 感觉这道题的计数方法好厉害.. 一个直观的思路是,把题目转化为求至少有\(k\)个极大的数的概率. 考虑这样一个事实,如果钦定\((1,1,1),(2,2,2),...,(k,k,k)\)是那\ ...
- codeforces111D. Petya and Coloring(组合数学,计数问题)
传送门: 解题思路: 要求一条直线分割矩阵时左右颜色数一样,那么就说明一个问题.直线左右移动时是不会改变左右矩阵的颜色集合的.所以说明:2~m-1列的颜色集一定属于第一列与第m列颜色集的交集.而且第一 ...
- UVAlive-7040 color(组合数学,二项式反演)
链接:vjudge 题目大意:有一排方格共 $n$ 个,现在有 $m$ 种颜色,要给这些方格染色,要求相邻两个格子的颜色不能相同.现在问恰好用了 $k$ 种颜色的合法方案数.答案对 $10^9+7$ ...
- [模板] 容斥原理: 二项式反演 / Stirling 反演 / min-max 容斥 / 子集反演 / 莫比乌斯反演
//待更qwq 反演原理 二项式反演 若 \[g_i=\sum_{j=1}^i {\binom ij} f_j\] , 则有 \[ f_i=\sum_{j=1}^i (-1)^{i-j} {i \ch ...
- P4859 已经没有什么好害怕的了(dp+二项式反演)
P4859 已经没有什么好害怕的了 啥是二项式反演(转) 如果你看不太懂二项式反演(比如我) 那么只需要记住:对于某两个$g(i),f(i)$ ---------------------------- ...
- 【LOJ#6374】网格(二项式反演,容斥)
[LOJ#6374]网格(二项式反演,容斥) 题面 LOJ 要从\((0,0)\)走到\((T_x,T_y)\),每次走的都是一个向量\((x,y)\),要求\(0\le x\le M_x,0\le ...
- 2018.11.07 hdu1465不容易系列之一(二项式反演)
传送门 其实标签只是搞笑的. 没那么难. 二项式反演只是杀鸡用牛刀而已. 这道题也只是让你n≤20n\le20n≤20的错排数而已. 还记得那个O(n)O(n)O(n)的递推式吗? 没错那个方法比我今 ...
- 洛谷4859 BZOJ3622 已经没什么好害怕的了(DP,二项式反演)
题目链接: 洛谷 BZOJ 题目大意:有两个长为 $n$ 的序列 $a,b$,问有多少种重排 $b$ 的方式,使得满足 $a_i>b_i$ 的 $i$ 的个数比满足 $a_i<b_i$ 的 ...
随机推荐
- HDU-3586 Information Disturbing(树形DP+删边)
题目大意:一棵有n个节点的有根树,1为根节点,边带权,表示删掉这条边的代价.现在要删掉一些边,使叶子节点不能到达根节点.但是,每次删除的边的代价不能超过limit,删掉的边的总代价不能超过m,求最小的 ...
- activity状态的保存和保持(onRetainNonConfigurationInstance和getLastNonConfigurationInstanc
本文转载于:http://chengbs.iteye.com/blog/1156167 比较onsaveinstancestate() 与 onretainnonconfigurationinstan ...
- CENTOS GUI
http://unix.stackexchange.com/questions/181503/how-to-install-desktop-environments-on-centos-7 How t ...
- 在Windows7上安装coreseek3.2同时在PHP下简单实现步骤
这两天安装了coreseek+sphinx服务,前面装的是比较低版本的,再试了一下官网比较稳定一个版本1.首先下载:因为包有点大,就不在这里增加链接了,需要可以到官网下载 coreseek-3.2.1 ...
- unity3d中切换武器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- FSM, VISIBILITY MAP AND VACUUM
Update: Heikki’s slides are here! Heikki Linnakangas gave a presentation this past Sunday at FOSDEM ...
- Ubuntu 安装和配置redis数据库
Ubuntu 14.04下安装和配置redis数据库 小编现在在写一个分布式爬虫,要用到这个数据库,所以分享一下小编是如何安装和配置的,希望对大家有帮助. 工具/原料 Ubuntu 系统电脑一台 ...
- 怎么给OCR文字识别软件设置正确的扫描分辨率
ABBYY FineReader 12是一款专业的OCR文字识别软件,可快速方便地将扫描纸质文档.PDF文件和数码相机的图像转换成可编辑.可搜索的文本,不仅支持对页扫描,还支持多页扫描,扫描分辨率的选 ...
- 009. C#中的WebBrowser控件的属性、方法及操作演示代码(转)
本文转自 http://www.open-open.com/code/view/1430559996802 0.常用方法 Navigate(string urlString):浏览urlString表 ...
- Rational Rose 安装及破解方法
Rational Rose 的安装与破解: 所需材料: 1.“Rational rose 2003.rar”安装包压缩文件 2.“license.rar”压缩文件(一 ...