绍兴一中模拟赛2.18——切蛋糕

本文详细探讨了三种不同复杂度的算法,用于计算矩形区域内的覆盖方案数量。从O(n^2)的直接枚举,到O(nlogn)的快速傅立叶变换优化,再到O(logn)的高效计算方法,每种算法都针对不同的需求提供了最优解决方案。

Description

Solution

n=h+wn=h+wn=h+w

1.O(n2)1.O(n^2)1.O(n2)

枚举行数iii和列数jjj
PhiP_h^iPhi代表hhh行里选了iii行的排列(与顺序无关,所以是排列)
PwjP_w^jPwj同理
但是两个排列只枚举了行与行和列与列之间的先后顺序,还不知道整个的先后顺序,那么再乘上一个Ci+jiC_{i+j}^iCi+ji就得到了整个的方案数
(i+1)(j+1)(i+1)(j+1)(i+1)(j+1)为此时的贡献
很多人会以为这样就好了,但事实上因为过程中的答案统计的不一定只有一次,所以每个方案要乘上它接下来的方案个数Pn−i−jk−i−jP_{n-i-j}^{k-i-j}Pnijkiji+ji+ji+j表示当前总操作次数,k−i−jk-i-jkij为剩下的操作次数),配张图:

这张图代表了答案的计算过程
我们发现1,2,31,2,31,2,3这三个点都经过了222次,要把这个东西统计进去
ans=∑i=0h∑j=0wPhiPwjCi+ji(i+1)(j+1)Pn−i−jk−i−jans=\sum_{i=0}^h\sum_{j=0}^wP_h^iP_w^jC_{i+j}^i(i+1)(j+1)P_{n-i-j}^{k-i-j}ans=i=0hj=0wPhiPwjCi+ji(i+1)(j+1)Pnijkij

2.O(nlogn)2.O(nlogn)2.O(nlogn)

把上式的ansansans拆开来,得到:
ans=h!w!(n−i−j)!(i+j)!(i+1)(j+1)i!j!(h−i)!(w−j)!n!ans=\frac{h!w!(n-i-j)!(i+j)!(i+1)(j+1)}{i!j!(h-i)!(w-j)!n!}ans=i!j!(hi)!(wj)!n!h!w!(nij)!(i+j)!(i+1)(j+1)
这东西可以用FFTFFTFFT优化

3.O(logn)3.O(logn)3.O(logn)

考虑到我们要统计矩形的个数,那么只要统计左下角同时被行列两条线经过(边界的点默认已经被边界线经过)的个数即可
那么,在计算第iii次分割的时候,不在边界上的点有Ci2Cn2\frac{C_i^2}{C_n^2}Cn2Ci2的概率被两条线切到(每次分割都会选怎么切,切到的两个数同时≤i≤ii的个数为Ci2C_i^2Ci2个,而切到数≤n≤nn的个数为Cn2C_n^2Cn2,所以概率为Ci2Cn2\frac{C_i^2}{C_n^2}Cn2Ci2
而这样的点有hwhwhw个,所以总数为(k−1)k(k+1)hw3n(n−1)\frac{(k-1)k(k+1)hw}{3n(n-1)}3n(n1)(k1)k(k+1)hw
对于在边界上,但不是左下角的点,概率为in\frac{i}{n}ni总共nnn个,总数为k(k+1)2\frac{k(k+1)}{2}2k(k+1)
左下角那个点每次概率为111kkk次后,总数为kkk
所以:ans=(k−1)k(k+1)hw3n(n−1)+k(k+1)2+kans=\frac{(k-1)k(k+1)hw}{3n(n-1)}+\frac{k(k+1)}{2}+kans=3n(n1)(k1)k(k+1)hw+2k(k+1)+k

Code

过程中有000的话要特判掉

#include<bits/stdc++.h>
using namespace std;
const int M=1e9+7;
long long h,w,k;
int n;
int pw(int x,int y){
	int z=1;
	for (;y;y>>=1,x=1ll*x*x%M)
		if (y&1) z=1ll*z*x%M;
	return z;
}
int main(){
	scanf("%lld%lld%lld",&h,&w,&k);
	h%=M,w%=M,k%=M,n=(h+w)%M;
	printf("%lld",(1ll*k*(k+1)%M*(k-1)%M*((M+1)/3)%M*(h?h:1)%M*(w?w:1)%M*(n==1?1:pw(1ll*n*(n-1)%M,M-2))+1ll*k*(k+1)/2+k)%M);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值