题解 CF653G Move by Prime

容易想到每个质数分开处理,每次操作就是次数加一或减一,目标就是让它们全部相等。

这是经典小学奥数问题,抽象成数轴上的点,找到一个点使该点到其余所有点距离和最小。首尾分组,容易发现这些点全部跳到中位数时最优。

xi 表示次数从小到大排序后第 i 大的数,M(x) 表示子序列中 xi 的中位数。

那问题转化为对所有子序列 |xiM(x)| 求和。

简单,M(x) 必定互相抵消。对于所有 xi 考虑其贡献。

j 表示比 xi 小的选了几个数,k 表示比 xi 大的选了几个数,分类讨论一下:

  • j<k,说明中位数比 xi 大,贡献为 xi

  • j=k,说明中位数等于 xi,贡献为 0

  • j>k,说明中位数比 xi 小,贡献为 xi

对于某些相等的 xi,不用在意它们是否会使答案计算产生错误,因为会互相抵消。于是可以认为 j[1,i),xj<xij(i,n],xj>xi,尽管某些 xjxi 相等。

所以 xi 对答案贡献为

j=1i1k=0j1(i1j)(nik)xij=0i1k=j+1ni(i1j)(nik)xi

这是组合数卷积的形式,尝试往范德蒙德卷积上靠,先考虑左边的系数。

尝试枚举 j+k 发现区间是 [j,2×j1],两个端点都是动的,这个不好。换枚举 jk,区间是 [1,j],这个好。

d=jk,有

j=1i1k=0j1(i1j)(nik)=d=1i1j=di1(i1j)(nijd)=d=1i1j=di1(i1j)(ninij+d)=d=1i1(n1ni+d)=d=ni+1n1(n1d)=d=ni+1n1(n1nd1)=d=0i2(n1d)

同理有

j=0i1k=j+1ni(i1j)(nik)=d=in1(n1d)

所以 xi 对答案的贡献为

[d=0i2(n1d)d=in1(n1d)]xi

预处理组合数前缀和即可做到 O(1) 计算,因为 3×105 以内的数最多有 6 个不同质因数,所以 xi0 的位置总共不超过 6n 个,直接做最坏也就 O(nlogw),可以通过。

或者说用 fi 表示 xi 的系数,对于相等的 xi 一块考虑,贡献为一段连续的 fi,预处理 fi 的前缀和即可。复杂度瓶颈在枚举 pk 的倍数,这是 O(wloglogw) 的。

posted @   Terac  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示