题解:P11110 [ROI 2023 Day 2] 陶陶装苹果
苹果的选取只与其重量
后续对苹果的选取若无特殊说明,均为
研究一维,即
将
(x,0) 视作一条射线上的一点,当(x,0) 为可到达对时视其为有色的点,有色的点组成一条或多条线段,则添加新的苹果i 到篮子中的过程相当于把有色点向正方向平移w_i 后与原来的有色点共存。
此时
可以发现这些有色的点连成了从点
对于上述射线中,初始有色的点为
因此令
回到我们二维的情况,我们继续将
苹果可以放在两个篮子里面,因此有色图形可以向两个方向平移。
当
当
不妨把
当
至此,我们将对于给定
空间复杂度为
时间上排序复杂度为
代码如下。
#include<bits/stdc++.h>
using namespace std;
constexpr int MAXN=3e5+10;
int n,q,z,pw,ptr;
long long w[MAXN],trlen[MAXN],tilen[MAXN],v;
int main(){
scanf("%d%d",&n,&q);
pw=n;
for(int i=1;i<=n;++i){
scanf("%lld",&w[i]);
}
sort(w+1,w+n+1);
for(int i=1;i<=n;++i){
if((w[i]<=(trlen[i-1]>>1)+1)&&tilen[i-1]==0){
trlen[i]=trlen[i-1]+w[i];
tilen[i]=0;
ptr=i;
}else if(trlen[i-1]+tilen[i-1]+1>=w[i]){
trlen[i]=min(trlen[i-1],trlen[i-1]+tilen[i-1]+1-w[i]);
tilen[i]=trlen[i-1]+tilen[i-1]+w[i]-trlen[i];
}else{
pw=i-1;
break;
}
}
scanf("%d",&z);
for(int i=1;i<=q;++i){
long long k,a,b;
scanf("%lld%lld%lld",&k,&a,&b);
k-=1ll*v*z;a-=1ll*v*z;b-=1ll*v*z;
int p=upper_bound(w+1,w+pw+1,k)-(w+1);//可用的物品 w[1]~w[p]
if(a>b)swap(a,b);//保证a<=b
if(p<=ptr){
if(a+b<=trlen[p]){
v+=i;
puts("Yes");
}else puts("No");
}else{
//lower_bound升序,在降序的数组中不可直接使用
int pp,l=ptr,r=p;
while(l<r){
#define mid ((l+r+1)>>1)
if(trlen[mid]>=a){
l=mid;
}else r=mid-1;
}
pp=l;
if(trlen[pp]>=a&&a+b<=tilen[pp]+trlen[pp]){
v+=i;
puts("Yes");
}else puts("No");
}
}
return 0;
}