[羅区P4602] CTSC2018ミックスフルーツジュース

問題の説明

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;
}

おすすめ

転載: www.cnblogs.com/LSlzf/p/11878957.html