문제 설명
R은 작은 어두운 요리, 특히 혼합 과일 주스를 할 싶어. 저장소는 N 과일 주스를 가지고 0, 1, 2,, N 번째 -... 1. 맛있는 주스의 I 번호는 파이의 리터 당 가격, 디입니다. 혼합 과일 주스의 생산에 작은 R, 즉 주스 병 혼합 특별한 규정이, 난 단지 주스 리 리터 번호를 추가 할 수 있습니다. 이제 그들은 주스 한 병에 혼합 약간의 R 저장소 주스를 만들기 위해 모든 희망, m 어린 아이들을 찾고은 R 혼합 된 과일 주스 음료에 와서있다. j 번째 얻은 주스를 혼합하는 것이 바람직 자신의 아이들은 총 가격 GJ, 이하 엘 제이 이외의 부피보다 크지된다. 이러한 제한에서, 아이들은 또한 가능한 한 높은 같은 과일 주스의 맛있는 혼합을 원하는 맛있는 혼합 과일 주스 한 병은 참여하는 모든 주스 혼합 맛도 최소 값과 같습니다. 각 아동의 과일 주스 혼합 음료의 가장 맛있는 맛을 계산하십시오.
입력 형식
파일에 juice.in에서 데이터를 읽습니다.
첫 번째 줄의 입력, 두 개의 양의 정수 N, m을 포함하는 아이의 수와 과일 주스의 종류의 수를 나타냅니다.
주스 병에 상한을 첨가 다음 N 라인 세 양수 디, PI는 리튬, 나 과일 주스 DI 수, PI 리터당 가격의 맛을을 나타내고, 각각의 라인은 리 내지.
다음 m 라인이 순차적으로 모든 아이를 설명 : 두 양의 정수의 각 행 GJ 번호를, 엘 제이 아이를 기술, 그가 주스의 적어도 엘 제이 리터를 원하는 그는 달러를 GJ까지 지불했다.
출력 형식
파일로 출력 Juice.out.
모든 어린이를위한 순차적으로 출력 : 각 자녀를 들면, 맛있는 주스의 가장 맛있는 혼합 학위를 마시 나타내는 정수를 포함하는 출력 한 줄. 당신이 자신의 요구를 충족 할 수없는 경우, 다음 출력 -1.
샘플 입력
3 4
1 3 5
2 1 3
3 2 5
6 3
5 3
10 10
20 10
샘플 출력
3
(2)
-1
1
설명
시험 된 모든 데이터는 N, m ≤ ≤ 디 100000,1, PI, 리튬 5,1 ≤ 10 ^ ≤ GJ LJ, ≤ 10 ^ 18을 보장하기 위해.
해결
재생 테이블과 형이상학의 방법으로 일련의 단조 답을 찾을 수 있습니다. 반 d를, 우리는보다 크거나 같은 D 주스를 선택할 수 있습니다. 이어서보다 큰 모든 D에 대해 설정 또는 다음 세그먼트 트리 목표 체중, 각 노드는 전체 부피 및 가격을 저장 주스의 가격 같다. 이 방법은 우리가 림의 오른쪽 절반에 트리 라인의 값을 사용할 수 있습니다.
하지만 다시 한 번 각 절반의 성과. 우리는이 문제를 해결하기 위해 지속성을 사용할 수있는 트리의 회장을 구축 할 수 있습니다.
코드
#include <iostream>
#include <cstdio>
#include <algorithm>
#define int long long
#define N 100002
#define T 100000
using namespace std;
struct ChairmanTree{
int l,r,suml,sump;
}t[N*40];
struct juice{
int d,p,l;
}a[N];
int n,m,i,g[N],L[N],root[N],p;
int read()
{
char c=getchar();
int w=0;
while(c<'0'||c>'9') c=getchar();
while(c<='9'&&c>='0'){
w=w*10+c-'0';
c=getchar();
}
return w;
}
int my_comp(const juice &x,const juice &y)
{
return x.d<y.d;
}
int insert(int pre,int l,int r,int L,int P)
{
p++;
int num=p;
t[p]=t[pre];
t[p].suml+=L;t[p].sump+=L*P;
if(l<r){
int mid=(l+r)/2;
if(P<=mid) t[p].l=insert(t[pre].l,l,mid,L,P);
else t[p].r=insert(t[pre].r,mid+1,r,L,P);
}
return num;
}
int ask(int p,int l,int r,int L)
{
if(l==r) return l*L;
int mid=(l+r)/2;
if(L<=t[t[p].l].suml) return ask(t[p].l,l,mid,L);
return t[t[p].l].sump+ask(t[p].r,mid+1,r,L-t[t[p].l].suml);
}
signed main()
{
n=read();m=read();
for(i=1;i<=n;i++) a[i].d=read(),a[i].p=read(),a[i].l=read();
for(i=1;i<=m;i++) g[i]=read(),L[i]=read();
a[0].d=-1;
sort(a+1,a+n+1,my_comp);
for(i=n;i>=1;i--) root[i]=insert(root[i+1],1,T,a[i].l,a[i].p);
for(i=1;i<=m;i++){
int l=1,r=T,mid,ans=0;
while(l<=r){
mid=(l+r)/2;
if(L[i]<=t[root[mid]].suml&&ask(root[mid],1,T,L[i])<=g[i]){
ans=mid;
l=mid+1;
}
else r=mid-1;
}
printf("%lld\n",a[ans].d);
}
return 0;
}