ATR143B Counting Grids 学习笔记
ATR143B Counting Grids 学习笔记
题意简述
现在需要将
。问合法方案数,答案对
做法解析
看起来就正难则反,不合法方案大概率比合法方案少且好算。
我们设不满足合法要求的元素为特殊元素,自然而然地我们要考虑其可能存在的数量,这关系到题目难度和是否使用容斥等工具。万幸地,这种特殊元素最多一个不然为什么洛谷只评了绿——如果有两个的话会相互矛盾(原因见图):
开始计算不合法方案数。首先特殊元素可以放在任何地方,是为
。合法方案数就是
代码实现
最后一步别忘了取模!
#include <bits/stdc++.h>
using namespace std;
namespace obasic{
typedef long long lolo;
template <typename _T>
void readi(_T &x){
_T k=1;x=0;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')k=-1;
for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-'0';
x*=k;return;
}
template <typename _T>
void writi(_T x){
if(x<0)putchar('-'),x=-x;
if(x>9)writi(x/10);
putchar(x%10+'0');
}
};
using namespace obasic;
const int MaxNs=2.5e5,Mod=998244353;
lolo facr[MaxNs],finv[MaxNs];
namespace omathe{
lolo fastpow(lolo a,lolo b,lolo p){
lolo res=1;
for(;b;(a*=a)%=p,b>>=1)if(b&1)(res*=a)%=p;
return res;
}
lolo getinv(lolo a,lolo p){
return fastpow(a,p-2,p);
}
lolo Aran(lolo n,lolo m,lolo p){
return facr[n]*finv[n-m]%Mod;
}
};
using namespace omathe;
void prework(int n){
facr[0]=finv[0]=1;
for(int i=1;i<=n;i++)facr[i]=facr[i-1]*i%Mod;
finv[n]=getinv(facr[n],Mod);
for(int i=n-1;~i;i--)finv[i]=finv[i+1]*(i+1)%Mod;
}
int N;lolo ans;
int main(){
readi(N);prework(N*N);
for(int i=N;i<=N*N-N+1;i++)(ans+=Aran(i-1,N-1,Mod)*Aran(N*N-i,N-1,Mod)%Mod)%=Mod;
(ans*=N*N*facr[(N-1)*(N-1)]%Mod)%=Mod;ans=(facr[N*N]+Mod-ans)%Mod;
writi(ans);
return 0;
}
反思总结
简单组合题,如果题目形如“不合法当且仅当有元素满足……”,而且这种元素数量大概不多,那就考虑它能有几个。
如果确认只有一个的话,难度可能就骤减了。
标签:
组合数学
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架