逆の順序でFZU2018レベルアルゴリズム2.10第2のジョブ数(重みツリーライン)

トピック:

  いくつかの最近の研究は逆のようなNK、列数は... A3、A2、nは... 1からなるA1、

  逆順A1 A2の数は...され、数がA1、A2の数と逆の数であるA3 ...に.An A2少数よりも、などの数よりも小さいです。

  例えば、列の数は、逆数列5,3,4,2,1 4,2,2,1,0です。

  だから、列数の逆の順序で与えられた数列ならば、あなたは彼のオリジナルシリーズを復元することができませんか?

  ★データ入力

  各テストデータは、正の整数nです。カラム長は、数(1 <= N <= 500)を示し、値の元の範囲内の列の数は[1、N]です。

  次いで、入力nは正の整数は(0 <= AI <N)愛

  ★データ出力

  スペースで区切られた2つの数値の間の中間オリジナルシリーズ出力、。

入力例 出力例
5
4 2 2 1 0
5 3 4 2 1

 

  最初の番号が記入見つけるのは難しいことではありません、問題の分析では、独自の以外のすべての数字は、その背後にあるので、最初の桁が4です。我々は、セットから、i番目のAIが彼のより少ない数を有する場合、第一の組におけるAI + 1はi番目の桁の大きい数であり、全ての数の組として、この数1〜Nであることができます削除されました。$ Oのnの値が(500ほど小さくないクロスセグメントツリーかかわらなく)が小さすぎるため、リストを完了するために使用されてもよい、セット保守複雑に使用することが可能である(N ^ {2})$、もちろん、セットアップし、より便利に書か維持、セットを維持することをお勧めします。ここで重みツリーラインを使用して、$ O(nlogn)$のアプローチを共有することができます。

最初のコードセットを貼り付け

#include <ビット/ STDC ++ H> 使用して名前空間STDを、
typedefの長い長いLL。
typedefの長いダブルLD; 
typedefの符号なしの長い長いULL。
typedefのペア < int型int型 > PII。
#define担当者(I、x、y)がため(I = xをint型、I yを<; I ++)
 の#define REPT(I、x、y)がため(I = xをint型、iは= yと<; iは++)
 の#define当たり(I、x、y)は(I = int型のX; I> = Y; i--)のため
 の#define PB一back
 の#define Fiの第一
 の#define SE第二
 の#define MES(B)のmemset(A、B、はsizeof A)


    const  int型 INF = 0x3f3f3f3f 

設定 < 整数 > 秒;
セット < 整数 > ::イテレータPOS。
int型のmain()
{ 
    IOS :: sync_with_stdio(); 
    cin.tie(0 )。
    int型のn; 
    cinを >> N; 
    REPT(I、1 、N)
        s.insert(I)。
    REPT(I、1 、N)
    { 
        場合(I- 1)COUT << "  " int型のx; 
        CIN>> X; 
        POS = s.begin()。 
        以下のためにint型 i = 0 ; iはXを<; iは、POSを++ ++ )。
        coutの << * POS。
        s.erase(POS)。
    } 
    COUT << " の\ n " リターン 0 ; 
}

 

  すべての1-Nの数、完了セグメントツリー、アレイのいくつかにポイントをマークし、i番目の各セグメントツリーのメンテナンス間隔の最大値を、各入力AI、第1のセグメントが、AIの数よりも大きい見つけるために間隔を残している点は、AIより大きく、左右のクエリ間隔がない区間の範囲を見つけるために残しました。双方向のi番目のアレイを想定し、各素子1の$ [1 + BI、N] $間隔を低減することができ、セグメントツリーは値0を割り当てであり両。

 

ACコードセグメントツリーを貼り付け

#include <ビット/ STDC ++ H> 使用して名前空間STDを、
typedefの長い長いLL。
typedefの長いダブルLD; 
typedefの符号なしの長い長いULL。
typedefのペア < int型int型 > PII。
#define担当者(I、x、y)がため(I = xをint型、I yを<; I ++)
 の#define REPT(I、x、y)がため(I = xをint型、iは= yと<; iは++)
 の#define PB一back
 の#define Fiの第一
 の#define SE第二
 の#define MES(B)のmemset(A、B、はsizeof A)CONST INT MAXN = 505

    

 
LLのarrcy [ 100005 ]。
クラスツリー// 线段树
{
     パブリックint型のL、R。
        LLプラス、ヴァル。
        ツリー()
        { 
            L = R =ヴァル=プラス= 0 
        } 
}ツリー[MAXN << 2 ]。

ボイドビルド(int型 ID、int型の L、INT R)。
ボイド追加(int型 ID、int型の L、int型のR、LLのNUM)。
無効 push_down(int型のID);
int型(見つけるint型の ID、int型NUM);
INT のmain()
{ 
    int型のn、X、ANS。
    cinを >> N; 
    ビルド(11 、N)
    担当者(I、0 、N)
    { 
        CIN >> X。
        ANS =見つける(1 、x)は、
        追加(1、ANS + 1、N - 1 )。
        (追加1を、ANS、ANS、 - N)。
        coutの << ANS << "  " ; 
    } 
    戻り 0; 
} 

ボイドビルド(int型 ID、int型の L、INT R)
{ 
    ツリー[ID] .L = L。
    ツリー[ID] .R = R。
    もし(L == R)
    { 
        ツリー[ID] .val =のL。
        返します
    } 
    INT半ば=(L + R)/ 2 
    構築(ID * 2 、L、ミッド)。
    ビルド(ID * 2 + 1、中間+ 1 、R)。
    ツリー[ID] .val = MAX(ツリー[ID * 2 ] .val、ツリー[ID *2 + 1 ] .val)。
} 
ボイド追加(int型 ID、int型の L、int型のR、LL NUM)
{ 
    場合(ツリー[ID] .L> = L &&ツリー[ID] .R <= R)
    { 
        ツリー[ID] .plus + = NUM。
        ツリー[ID] .val + = NUM。
        返します
    } 
    もし(ツリー[ID] .L> R ||ツリー[ID] .R <L)のリターン; 
    push_down(ID)。
    もし(ツリー[ID * 2 ] .R> = 1)(ID *追加2 、L、R、NUM)を、
    もし(ツリー[ID * 2 + 1] .L <= R)を追加(ID * 2 + 1 、L、R、NUM)。
    ツリー[ID] .val = MAX(ツリー[ID * 2 ] .val、ツリー[ID * 2 + 1 ] .val)。    
} 
ボイド push_down(int型のID)
{ 
    REPT(J、ID * 2、ID * 2 + 1 
    { 
        ツリー[J] .val + = ツリー[ID] .plus。
        ツリー[J] .plus + = ツリー[ID] .plus。
    } 
    ツリー[ID] .plus = 0 
} 
int型の検索(int型 ID、INTNUM)
{ 
    場合(ツリー[ID] .L ==ツリー[ID] .R)リターン・ツリー[ID] .L。
    push_down(ID)。
    もし(ツリー[ID * 2 ] .val> NUM)戻り検索(ID * 2 、NUM)。
    他の リターンのfind(ID * 2 + 1 、NUM); 
}

 

おすすめ

転載: www.cnblogs.com/FZUzyz/p/11516357.html