P6475 [NOI Online #2 入门组]建设城市 |组合数学
作者:互联网
题目描述
球球是一位建筑师。一天,他收到市长的任务:建设城市。球球打算建造 \(2n\) 座高楼。为了保证城市美观,球球做出了如下计划:
球球喜欢整齐的事物。他希望高楼从左向右排成一行,编号依次为 \(1\sim 2n\)。
球球喜欢整数,他要求每座高楼的高度都是正整数。
由于材料限制,高楼的高度无法超过 \(m\)。
球球喜欢中间高,两边低的造型。他要求前 \(n\) 座高楼的高度不下降,后 \(n\) 座高楼的高度不上升。
球球打算选两座编号为 \(x,y\) 的高楼作为这座城市的地标。他认为只有当这两座高楼高度相等时,才会让城市变得美观。
球球把自己的想法告诉了市长。市长希望得知所有建设城市的方案数。两种方案不同,当且仅当某座高楼的高度在两个方案中不同。这个问题可难倒了球球。球球找到了你,希望你能帮他算出答案。由于答案可能很大,你只需要给出答案对 \(998244353\) 取模后的结果。
输入格式
从标准输入读入数据。
仅一行四个整数 \(m,n,x,y\),变量意义见题目描述。
输出格式
输出到标准输出。
仅一行一个整数表示答案。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int N=2e5+10,M=2e5,mod=998244353;
#define int long long
inline int ksm(int x,int y){
int ans=1;
while(y){
if(y&1)ans=ans*x%mod;
x=x*x%mod; y>>=1;
}
return ans;
}
int n,m,x,y;
int jc[N],inv[N];
inline void pre(){
jc[0]=1; for(int i=1;i<=M;i++)jc[i]=jc[i-1]*i%mod;
inv[M]=ksm(jc[M],mod-2);
for(int i=M-1;i>=0;i--)inv[i]=inv[i+1]*(i+1)%mod;
}
inline int C(int x,int y){
if(y>x)return 0;
return jc[x]*inv[x-y]%mod*inv[y]%mod;
}
inline int f(int x,int y){
return C(x+y-1,y-1);
}
signed main(){
pre(); cin>>m>>n>>x>>y;
if(y<=n||x>n){
printf("%lld\n",f(n+x-y,m)*f(n,m)%mod);
}else{
int ans=0;
for(int i=1;i<=m;i++)
ans=(ans+f(x-1,i)*f(n-x,m-i+1)%mod*f(y-n-1,m-i+1)%mod*f(2*n-y,i)%mod)%mod;
printf("%lld\n",ans);
}
}
标签:include,NOI,int,inv,球球,高楼,Online,P6475,mod 来源: https://www.cnblogs.com/naruto-mzx/p/12787807.html