「ARC133E」Cyclic Medians 题解
本文网址:https://www.cnblogs.com/zsc985246/p/17513317.html ,转载请注明出处。
传送门
题目大意
给定 ,你需要计算所有长为 、值域为 的整数序列 和长为 、值域为 的整数序列 形成的序列对 的价值和。
序列对 的价值由如下过程定义:
- 令 。
- 从 到 枚举 ,每次让 变成 的中位数。
- 价值为 最后的值。
答案对 取模。
。
思路
套路:枚举 ,统计中位数 的方案数,加起来就是所有方案的中位数的总和。
我们可以枚举 ,然后将 和 中所有 的数设为 , 的数设为 ,统计中位数 的方案数。
现在一次操作 只有三种情况:。
如果是 ,那么 ,如果是 ,那么 ,否则 不变。
发现如果有 的操作,那么 的值就与 无关了。
所以我们把有 操作的情况和无 操作的情况分开算。
对于有 操作的情况,显然最后一次 操作会决定 最终的结果。
所以我们只需要统计最后一次 操作满足 的方案。
我们发现,因为我们的 和 是任意取,所以在 时某次操作 的方案数与 时这次操作 的方案数相等。也就是说,方案具有对称性。
所以我们只需要用总方案 减去无 操作的方案数,然后除以 就是 的方案。
现在考虑无 操作的情况。
思考发现,如果 ,那么每个数 都会正好与每个 组成一次 数对。
进一步发现,如果 ,那么一个数 只可能与所有数 组成数对。
所以必须满足 。
拆开其实就是三个条件:
- ;
- ;
- 。
那么分别计算 取 和 ,方案数为
因为 ,所以还需要再进行 次方。即
然后将两种情况的答案加起来就做完了。时间复杂度 。
代码实现
#include<bits/stdc++.h>
#define ll long long
#define For(i,a,b) for(ll i=(a);i<=(b);++i)
const ll N=1e6+10;
using namespace std;
const ll p=998244353;
ll ksm(ll a,ll b){ll bns=1;while(b){if(b&1)bns=bns*a%p;a=a*a%p;b>>=1;}return bns;}
ll n,m,k,A;
int main(){
scanf("%lld%lld%lld%lld",&n,&m,&k,&A);
ll ans=ksm(k,n+m);
ll g=__gcd(n,m);
For(i,1,k-1){
ll t=ksm((ksm(i,n/g)*ksm(k-i,m/g)+ksm(k-i,n/g)*ksm(i,m/g))%p,g);
if(A>i)ans=(ans+t)%p;
ans=(ans+(ksm(k,n+m)-t+p)*499122177)%p;//499122177是2在模998244353下的逆元
}
printf("%lld",ans);
return 0;
}
尾声
如果你发现了问题,你可以直接回复这篇题解
如果你有更好的想法,也可以直接回复!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现