サンクトペテルブルクへの旅

トピックリンク:https://codeforces.com/contest/1250/problem/C

質問の意味:あなたは街で仕事を探している、そこにNジョブは、各営業日のR初日にLからの仕事は、恵みWを取得します、あなたはより多くの同じ時よりもパートタイムで働くことができるかどうかですが、限り、あなたは街でこの日であるとしてあなたはK元を失うことになる、と今では都市の最初の数に数日間に数日からご滞在のあなたの最大の利益と出力をエクスポートし、作業に参加し、あなたがとにかく利益することができない場合は、出力0することができます。

思考:セグメントツリーは、一日あたりの最初の損失は、作業している場合、Lが発注作業に報酬を与えるために加え、得られたRの最初の作業、作業のそれぞれ、列挙には、端点を左、線k進ツリーに追加されました[I] .Lは以下左端点よりも、それが前に除去OFF [I]報酬A .Rに追加されます。押して、その後Rの仕事と同じ種類の、そして最大の利益の最大の利益として大きなとして、この時点であれば、右のポイントを列挙し、左のポイントを列挙し、次に右の点を見つけ、どのような作業は、この間隔で見ることができます。

// の#include <ビット/ STDC ++。H> 
の#include <stdio.hに> 
する#include < 文字列・H> 
の#include <math.h>の
書式#include < ストリング > 
の#include <iostreamの> 
する#include <アルゴリズム> 
する#include <キュー> 
の#include <>マップ
 使って 名前空間はstdを、
typedefの長い 長いLL。
const  int型 MAXN = 200010 ;
int型B [MAXN]。
構造体トゥーレ
{ 
    LLのL、R、日付、のLaz。
} T [MAXN * 4 ]。
構造体ノード
{ 
    W LLのL、R、。
    LL ID; 
} [MAXN]。
ブールCMP(ノードX、ノードY)
{ 
    場合(XL == イル)
         戻り XR < 年。
    戻り <XL イル。
} 
ブールCMP1(ノードX、ノードY)
{ 
    戻り XR < 年。
} 
ボイドビルド(LL P、LL、L、LL R)
{ 
    T [P] .L = L。
    T [P] .R = R。
    T [P] .date = T [P] .laz = 0 もし(L == R)の
         リターン;
    LL半ば =(L + R)/ 2 
    ビルド(P * 2 、L、ミッド)。
    ビルド(P * 2 + 1、ミッド+ 1 、R); 
} 
ボイド更新(LL P、LL、L、LL R、LL V)
{ 
    もし(T [P] .L> = L && T [P] .R <= R)
    { 
        T [P] .date + = V。
        T [P] .laz + = V。
        リターン; 
    } 
    LL半ば =(T [P] .L + T [P] .R)/ 2 もし(T [P] .laz)
    { 
        T [P * 2 ] .laz + =T [P] .laz。
        T [P * 2 + 1 ] .laz + = T [P] .laz。
        T [P * 2 ] .date + = T [P] .laz。
        T [P * 2 + 1 ] .date + = T [P] .laz。
        T [P] .laz = 0 
    } 
    であれば(MID < L)
        更新(P * 2 + 1 、L、R、V)。
    そう であれば(MID> = R)
        更新(P * 2 、L、R、V)。
    他の
    { 
        更新(P *2 、L、中、V)。
        更新(P * 2 + 1、中間+ 1 、R、V)。
    } 
    T [P] .date = MAX(T [P * 2 ] .date、T [P * 2 + 1 ] .date)。
} 
int型のmain()
{ 
    LL N、K、MA = 0 
    CIN >> N >> K。
    以下のためにINT iが= 1 ; I <= N; I ++ 
    { 
        CIN >> [I] .L >> [I] .R >> [I] .W。
        [I] .ID = I。
        MA =MAX(MA、[I] .R)。
    } 
    ビルド(11 、MA)。
    ソート( + 1、+ N + 1 、CMP)。
    以下のためにINT iが= 1 ; I <= MA; I ++ 
        更新(1、I、MA、 - K)。
    以下のためにINT iが= 1 ; I <= N; I ++ 
        更新(1 、[I] .R、MA、[I] .W)。
    LL、X = 1、MAXX = 0 、L、R。
    以下のためにINT iが= 1、I <= MAを; I ++
    { 
        一方(I> [X] .L && X <= N)
        { 
            更新(1、[X] .R、MA、 - [X] .W)。
            X ++ ; 
        } 
        であれば(MAXX <T [ 1 ] .date)
        { 
            MAXX = T [ 1 ] .date。
            L = I; 
        } 
        更新(1 、I、MA、K)。
    } 
    であれば(MAXX <= 0 
    { 
        COUT << " 0 " << ENDL。
        リターン 0 ;
    } 
    ビルド(11 、MA)。
    以下のためにINT iがLを=; I <= MA; I ++ 
        更新(1、I、MA、 - K)。
    ソート( + 1、+ N + 1 、CMP1)。
    以下のためにINT iが= 1 ; I <= N; I ++ 
    { 
        場合([i]が.L> = L)
        { 
            更新(1 、[I] .R、MA、[I] .W)。
            R = [I] .R。
        } 
        もし(T [ 1 ] .date == MAXX)
            休憩; 
    } 
    int型の H = 0 以下のためにINT iが= 1 ; I <= N; I ++ 
    { 
        場合([i]が.L> = L && [I]。R <= R)
            B [ ++ H] = [I] .ID。
    } 
    COUT << MAXX << "  " << L << "  " << R << "  " << H << ENDL。
    以下のためにINT iが= 1 ; I <= H; I ++ 
        COUT << B [i]は<< "  " ; 
    coutのてendl;<<
}

 

おすすめ

転載: www.cnblogs.com/zcb123456789/p/12622233.html