P7868 VUDU 题解

P7868 VUDU 题解

提供一种不需要使用离散化,从0/1分数规划的角度推导的思路。然而考试的时候没想到求逆序对挂掉了

分析

题意很清楚了,就是求给出的序列中,对于一段任意长度的连续区间,其元素和的平均数大于等于p的种数,可以用如下式子来表达:

i=lra[i]rl+1p

推导方法1

当时写出来这个式子,我一眼0/1分数规划,WhichIsKnownAs

i=lra[i]x[i]i=lrb[i]x[i]mid

但是这道题只能选连续的一段,所以x[i]就不存在了

当然如果你不知道0/1分数规划,也完全没有关系,往下看就是了。

我们把第一个式子里面的rl+1想办法变成第二个式子里面的b[i],通过对比很容易发现,我们假设所有的b[i]=1,那么就有:

i=lra[i]rl+1pi=lra[i]i=lrb[i]pi=lra[i]p×i=lrb[i]0i=lr(a[i]p×b[i])0

不要忘了其中b[i]=1,于是上面的式子就最终变成了i=lr(a[i]p)0

其中a[i],p都是定值,于是我们记v[i]=a[i]p,最终我们就把题意变成了从v[i]中,选出子段和大于等于0的方案数

推导方法2

如果您认为上面太麻烦了,那么下面的应该更容易理解了,先回到原来的式子:

i=lra[i]rl+1p

同样的化化简,移移项:

i=lra[i]rl+1pi=lra[i](rl+1)×p0

如何感性理解上式?

注意到有rl+1a[i]在求和,还要减去rl+1p,即判断k个数减去kp之后的值,是否非负。

那么我们把每个p均摊到每一个a[i]上面,就有了我们用第一种方法推导出的:i=lr(a[i]p)0

引入前缀和

问题来到了如何快速求一段区间和?我们自然地想到了前缀和,用sum[r]sum[l1]快速地求出区间和

我们发现对于每一个1lrn,只要满足sum[r]sum[l1]0,即[l,r]中元素和大于等于0,就一定能对答案产生1的贡献。

这里随便口胡一个sum序列:0,1,3,6,2,3,1,5,比如其中1,3就可以构成一个答案,表示[2,5]的区间和为3(1)=4

顺序对、逆序对

手玩几组样例就会发现,我们求的其实就是其中顺序对的数量,特别地对于l=1的情况,sum[l1]=sum[0]=0,我们也是需要考虑的,它的实际意义就是[1,r]的区间和。

然后我们再倒过来思考一下,就把顺序对转化成了逆序对。

假设我们把前缀和数组倒过来之后,更具体地说:lr,sum[l]sum[r]就是本题中一个符合条件的情况

小细节

注意要开longlong

Code

posted @   Hanggoash  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
动态线条
动态线条end
点击右上角即可分享
微信分享提示