AT_abc297_f [ABC297F] Minimum Bounding Box 2 题解
水。
题目就是说,给你一个
算期望,那么转换为算方案数。
容斥当然是最好的解决办法!
考虑枚举网格上的每个位置
但是这东西看上去不大好求啊!
常规套路,正难则反呗。不能正着直接求,那咱就反过来,容斥。
所以现在需要计算的就是有多少张网完全不包含
让剩下
令这个玩意儿为
但是这样对……吗?
没错确实不对,因为会重复算啊!比方说左上角的,就会被上和左各算一次,这可不行!
因此就轮到咱们的容斥出场啦!
左上角、右上角、左下角、右下角都会重复算,画几张图摇一摇,又会出现下面的公式:
咱又令这家伙为
那么
但在此之前还需要算一个
所以最终
说到这里,整个做法也就显而易见了。枚举每个
时间复杂度
代码也是非常短的。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int K = 1e6+5;
const LL mod = 998244353;
LL n,m,k,p[K],v[K],All,ans;
LL QP(LL x,LL y){LL as=1;while(y){if(y&1)as=(as*x)%mod;x=(x*x)%mod,y>>=1;}return as;}
LL C(LL x,LL y){if(x<y)return 0;return ((p[x]*v[y])%mod*v[x-y])%mod;}
int main(){
cin>>n>>m>>k;p[0]=1,v[0]=1,ans=0;
for(LL i=1;i<=n*m;i++)p[i]=(p[i-1]*i)%mod,v[i]=QP(p[i],mod-2);All=C(n*m,k);
for(LL i=1;i<=n;i++)for(LL j=1;j<=m;j++){
LL add=(C((i-1)*m,k)+C((n-i)*m,k)+C((j-1)*n,k)+C((m-j)*n,k))%mod;
LL div=(C((i-1)*(j-1),k)+C((n-i)*(j-1),k)+C((i-1)*(m-j),k)+C((n-i)*(m-j),k))%mod;
LL now=(All-(add-div)+mod)%mod;ans=(ans+now)%mod;
}
cout<<(ans*QP(All,mod-2))%mod<<"\n";
return 0;
}
如果本篇题解对你有帮助的话,麻烦你点一个小小的赞,真是太谢谢啦!