CF1503E 2-Coloring
CF1503E 2-Coloring
cjx 组合强。
思路
观察一下题目,不难发现只有当黄色形成如下的单峰时才合法。
(染错色了,将就一下)
其中两座峰的峰顶高度相加等于
发现对于每一边是两个最长不下降子序列拼在一起。
设
再设
答案就是
相当于枚举第一个峰在行
变幻一下:
这样给后一个和式做一个后缀和优化,即可把复杂度优化到
当然有例外是这个样子。
两峰交在一起(必须保证在连续的行且峰顶高度相加大于
相当于枚举左边的峰顶在行
对于
然后预处理出所有的
再次前缀和。
即可在
对于
初始值
其实你看到这里,已经可以使用 dp 做出本题了,但是如果你想进一步了解组合,请移步。
不难发现,我们每次的转移都相当于求一次前缀和,而
所以有可以构造这样的生成函数:
观察
而
由
推广一下,每次
对于
所以有:
使用广义二项式展开
关于牛顿二项式系数,已经有完备的公式,本处直接套公式即可,故不再展开讨论。
把系数乘上
从比较简单的组合意义考虑,有
那么有:
在观察一下
所以其实你也求出
相当于有
如果考虑生成函数的话,
或
于是你就可以 愉快 的 AC 本题了。
CODE
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 5000
#define mod 998244353
const int maxn=5e3+5;
ll n,m,ans;
ll fac[maxn],inv[maxn],f[maxn];
inline ll ksm(ll x,ll y)
{
ll sum=1;
for(;y;y/=2,x=x*x%mod) if(y&1) sum=sum*x%mod;
return sum;
}
inline ll C(int n,int m)
{
if(n<m||m<0) return 0;
return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main()
{
freopen("magic.in","r",stdin);
freopen("magic.out","w",stdout);
for(int i=fac[0]=1;i<=N;i++) fac[i]=fac[i-1]*i%mod;
inv[N]=ksm(fac[N],mod-2);
for(int i=N-1;~i;i--) inv[i]=inv[i+1]*(i+1)%mod;
scanf("%lld%lld",&n,&m);
for(int h=1;h<n;h++)
{
for(int j=m;j>=2;j--)
{
f[j]=(1LL*f[j+1]+1LL*C(j+n-h-2,n-h-1)*C(m-j+n-h,n-h)%mod)%mod;
}
for(int i=m-1;i>=1;i--)
{
ans = (1LL*ans+1LL*C(i+h-1,h)*C(m-i+1+h-2,h-1)%mod*f[i+1]%mod)%mod;
}
}
memset(f,0,sizeof(f));
for(int x=1;x<=m;x++)
{
for(int j=n-1;j>=1;j--)
{
f[j]=(1LL*f[j+1]+1LL*C(m-x+n-j-1,n-j-1)*C(m-x+j-1,j)%mod)%mod;
}
for(int i=1;i<n;i++)
{
ans=(1LL*ans+1LL*C(x+i-1,i)*C(x+n-i-1,n-i-1)%mod*f[n-i+1]%mod)%mod;
}
}
printf("%lld\n",ans*2%mod);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现