atcoder grand contest 040 F Two Pieces
传送门:https://atcoder.jp/contests/agc040/tasks/agc040_f
sol:
首先 这题我不会
看了官方的题解才会的……这里只是写一下自己的理解x
如果有错可以私聊我qwq
我们现在用表示一个状态
这个状态定义为比较大的那个点在位置,两个点之间的距离是
接下来我们就可以把操作抽象成如下的三个东西
把和同时
把
把设为
接下来我们就考虑先做操作和操作
假设我们已经排列好了和操作,考虑怎么把操作插入这个序列中
考虑操作能插入的位置
抄一段题解x
the value of d will never be equal to or less than its current value again.
也就是说只能把插入不会比后面任何大的情况操作的后面
在插入完操作的时候,的值要是
所以我们必须插入 其中的值最终是的时候
将的其余次,插入到最后一次值变为的任何位置。
于是我们考虑枚举一个
我们可以分开处理操作和操作的总方案和插入的方案
和的操作可以类似数的操作,考虑枚举一个位置不合法之后翻转一下
翻转完之后就可以直接统计
操作是个经典的隔板
然后就好像做完了x
#include <bits/stdc++.h> using namespace std; int N,a,b,ans; int fac[10000005],inv[10000005]; const int fish=998244353; int Pow(int x,int y){ int ans=1; for (;y;y>>=1,x=1ll*x*x%fish) if (y&1) ans=1ll*ans*x%fish; return ans; } void Pre(){ fac[0]=1; for (int i=1;i<=10000000;i++) fac[i]=1ll*fac[i-1]*i%fish; inv[10000000]=Pow(fac[10000000],fish-2); for (int i=9999999;i>=0;i--) inv[i]=1ll*inv[i+1]*(i+1)%fish; } int C(int n,int r){return 1ll*fac[n]*inv[r]%fish*inv[n-r]%fish;} int catalan(int x,int y){return ((C(x+y,y)-C(x+y,y-1))+fish)%fish;} int main(){ Pre(); scanf("%d%d%d",&N,&a,&b); if (b==0){ cout<<1; return 0; } for (int i=0;i<=min(min(a,N-b),b-1);i++){ int tot=catalan(b-1,i); if (i+b==N){ if (a==i) (ans+=tot)%=fish; } else { int x=N-b-i-1; int y=b-i-(b-a)+1; (ans+=1ll*tot*C(x+y-1,x)%fish)%=fish; } } cout<<ans; }
干啥啥不行
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?