天下何人比我弱系列
太难啦!!!
我CTSC花了整整2.5小时才AC
您要是做过CQOI2015任务查询系统就不会蒙蔽了
但是
我是一个SC考生!!!
可怕的ABNS历历在目!!!
那个也是配合饮料!!!
而且是一个可持久化平衡树维护动态二维凸包!!
于是我认为这是一个平衡树维护三维动态凸包
但是我TM又不是傻逼我也知道子任务!!!
于是乎在完成子任务13_15时我想到了主席树!!!
随后->这不就是个原题吗?
水过。
他不是凸包的原因是:这是一个可贪心模型
以d值为根,以p值(离散化)为键值建树查就是了。
唯一的trick还在CQOI2015考过了就是考虑sum是否足够
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int N=1e5*26+10;
const int M=1e5+100;
typedef int INT;
#define LL long long
#define int long long
inline void read(LL &x){
x=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
LL n;
LL m;
struct Goods{
LL d,p,l;
double w;
}e[M];
int root[N]={};
int lson[N]={};
int rson[N]={};
int sum[N]={};
int val[N]={};
int mmp[M]={};
int cnt=1;
void update(int x,int &y,int l,int r,int v,int k){// v is the key
//cout<<l<<" "<<r<<" "<<k<<'\n';
cnt++;
y=cnt;
lson[y]=lson[x];
rson[y]=rson[x];
sum[y]=sum[x]+k;
val[y]=val[x]+k*mmp[v];
if(l==r)return;
//cout<<x<<" "<<y<<" "<<l<<" "<<r<<" "<<sum[y]<<'\n';
int mid=(l+r)/2;
if(v<=mid)update(lson[x],lson[y],l,mid,v,k);
else update(rson[x],rson[y],mid+1,r,v,k);
}
/*int query(int y,int l,int r,int k){
int t=sum[lson[y]];
//cout<<y<<" "<<l<<" "<<r<<" "<<k<<" "<<sum[lson[y]]<<" "<<val[lson[y]]<<" "<<t<<'\n';
if(l==r){
return k*mmp[l];
}
int mid=(l+r)/2;
if(t<k){
return val[lson[y]]+query(rson[y],mid+1,r,k-t);
}
else return query(lson[y],l,mid,k);
}*/
int query(int x,int y,int l,int r,int k){
int t=sum[lson[y]]-sum[lson[x]];
//cout<<y<<" "<<l<<" "<<r<<" "<<k<<" "<<sum[lson[y]]<<" "<<val[lson[y]]<<" "<<t<<'\n';
if(l==r){
return k*mmp[l];
}
int mid=(l+r)/2;
if(t<k){
return val[lson[y]]-val[lson[x]]+query(rson[x],rson[y],mid+1,r,k-t);
}
else return query(lson[x],lson[y],l,mid,k);
}
bool cmpC(Goods A,Goods B){
return A.d<B.d;
}
int d_sum[M]={};
int Maxd=-1;
int len;
bool check(int idx,int l,int g){
if(d_sum[Maxd]-d_sum[idx-1]<l)
return false;
if(query(root[idx-1],root[Maxd],1,len,l)<=g)return true;
else return false;
}
INT main(){
freopen("juice.in","r",stdin);
freopen("juice.out","w",stdout);
read(n);
read(m);
for(int i=1;i<=n;i++){
read(e[i].d);
Maxd=max(Maxd,e[i].d);
read(e[i].p);
read(e[i].l);
d_sum[e[i].d]+=e[i].l;
mmp[i]=e[i].p;
}
sort(mmp+1,mmp+1+n);
len=unique(mmp+1,mmp+1+n)-mmp-1;
for(int i=1;i<=n;i++){
//cout<<e[i].p<<" ";
e[i].p=lower_bound(mmp+1,mmp+1+len,e[i].p)-mmp;
//cout<<e[i].p<<'\n';
}
sort(e+1,e+1+n,cmpC);
e[0].d=0;
for(int i=1;i<=n;i++){
//cout<<i<<'\n';
if(e[i].d!=e[i-1].d){
for(int l=e[i-1].d+1;l<=e[i].d-1;l++){
update(root[l-1],root[l],1,len,0,0);
}
update(root[e[i].d-1],root[e[i].d],1,len,e[i].p,e[i].l);
}
else update(root[e[i].d],root[e[i].d],1,len,e[i].p,e[i].l);
}
update(root[Maxd],root[Maxd+1],1,len,0,0);
//cout<<Maxd<<'\n';
for(int i=1;i<=Maxd+1;i++){
d_sum[i]+=d_sum[i-1];
}
//cout<<query(root[2],root[Maxd],1,len,3);
for(int i=1;i<=m;i++){
int g,l;
read(g);
read(l);
int L=0;
int R=Maxd+1;
int ret=-1;
while(L<=R){
int mid=(L+R)/2;
if(check(mid,l,g)){
ret=mid;
L=mid+1;
}
else R=mid-1;
}
printf("%lld\n",ret);
}
//cout<<root[2];
//cout<<query(root[1],root[5],1,len,4);
//cout<<cnt;
return 0;
}