問題の説明
Rは、小さな暗い料理、特にミックスフルーツジュースを行うことを熱望します。ストアは、n個のフルーツジュースを持っていた0、1、2番,, N -... 1。おいしいジュースのI番号は、PIのリットル当たりの価格、ジです。ミックスフルーツジュースの生産で小R、すなわちジュースの瓶の中に混入し、いくつかの特別な規定が、ありますが、私は数字だけジュースのliリットルを追加することができます。今、小さな子供たちを探して、mはR混合果汁飲料にそこに来ている、彼らはすべてのジュースの瓶の中に混ぜ少しRストアジュースを作りたいです。j番目の取得汁を混ぜることが望ましい彼の子供たちは、合計金額GJ、以下Ljを超えるの容積よりも大きくないことを特徴とします。これらの制約の下で、子どもたちもできるだけ高いとしてフルーツジュースのおいしいミックスをしたい、おいしいミックスフルーツジュースのボトルは、すべての参加ジュース混合おいしい度の最小値に等しいです。それぞれの子のフルーツジュースミックスドリンクの一番美味しい味を計算してください。
入力形式
ファイルがでjuice.inからデータを読み込みます。
最初の行の入力は、2つの正の整数N、Mが含まれている子どもの数やフルーツジュースの種類の数を表します。
ジュースのボトルの上限を追加次のn行、3つの正の整数ジ、piは、Liは、iは果汁DI番号、PIのリットル当たりの価格の美味しさを表し、各行は、リチウムからです。
次メートルラインは順次すべての子を説明します。正の整数の各行のGJ数が2、Ljの子を説明し、彼はジュースの少なくとものLJリットルで望んでいる、彼はGJドルまで支払ったと述べました。
出力フォーマット
ファイルに出力Juice.out。
すべての子供のための順次出力:各生徒用、おいしいジュースを飲む彼度の最もおいしいミックスを表す整数を含む出力1行。あなたは自分のニーズを満たすことができない場合は、出力-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、リチウム≤10 ^ 5,1≤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;
}