Gym 101630G The Great Wall

题意:

三个有n个正整数的数组满足a[i]<b[i]<c[i],固定一个r,根据不同的x,y生成不同的数列,每对合法的x,y(x<y)生成两个区间[x,x+r-1],[y,y+r-1],合法指生成的区间不会越界,如果一个点i被两个区间覆盖,他的值就是c[i],如果被一个覆盖就是b[i],否则a[i],一个数列的价值等于所有点的值之和,问在所有x,y生成的序列中价值第k大的是多少

分析:

首先把b[i],c[i]减去a[i],最后再加回来方便计算

这种第k大的经典套路就是二分答案check有多少个值比他小

在这个题的check里,我们分两部分讨论:x和y的区间有重叠的和没有重叠的,对于没有重叠的十分容易,枚举每个点作为右区间的起始端点再离散化区间b[i]的和用树状数组统计与多少个前面的区间值相加<mid即可

对于重叠的,表面上看重叠区间之间会互相影响,无法像不重叠那样直接将区间b[i]和插入树状数组

这就需要将加入树状数组的值凑成一个只与当前点相关的值,具体凑法如下:

 

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
#define sc(x) scanf("%d", &x)
#define pb push_back
#define ALL(x) x.begin(),x
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值