【NOI2019]バウンス

リンク

$ソリューション:$

激しくセグメントツリーをすることができます。

各セグメントのツリーノードが集合$ $、$ X $メモリ・セグメントの木軸、メンテナンスの$ $の$ Yの$のSET軸は、各$ $ダイクストラに何らかの暴力を取る維持などの単純なアプローチがあります。

^ 2つのn $点のほとんどの$ n \ログのツリーラインため、だけでなく、直接エッジに接続されていない。この点を取り、動的なメンテナンス、後セグメントツリーを削除します。

すなわち、空間的な複雑さの$ O $、時間複雑性の$ O((N ^ 2 n個)\ログをログ\(N ^ 2のnを記録\))$(N ^ 2のnを記録\)。

書式#include <iostreamの> 
の#include <cstdioを> 
する#include <CStringの> 
の#include <アルゴリズム> 
書式#include < 設定 > 
書式#include <キュー>
 使用して 名前空間はstd; 
インラインint型リード(){
     int型 = F 1、ANS = 0チャー C = GETCHAR()。
    一方、(C < ' 0 ' || C> ' 9 '){ もし、(C == ' - ')、F = - 1 ; C = GETCHAR();}
    一方、(C> = ' 0 ' && C <= ' 9 '){ANS = ANS * 10 + C- ' 0 ' ; C = GETCHAR();}
     戻りのF *のANS。
} 
のconst  int型 MAXN = 150001 
PRIORITY_QUEUE <ペア< int型int型 >> QUE。
セット <ペア< 整数整数 >> S [MAXN << 2 ]。
INT DIS [MAXN << 2 ]、VIS [MAXN << 2 ]、ヘッド[MAXN]、CNT。
構造体SPE {
     int型X、Y。
} G [MAXN]。
構造体セグメント{
     ボイドは(変更int型 K、int型の L、int型の R、int型のx、int型の Y、int型のID){ 
        S [k]は.insert(make_pair(G [ID] .Y、IDを)); 
        もし(L == R)のリターン;
        INT半ば= L + R >> 1 もし(x <= MID)(K <<変更1 、L、中、X、Y、ID)。
        もし(K <<(MID <y)の修正1 | 1、中間+ 1 ;、R、X、Y、ID)
        リターン
    }
    ボイドクエリ(int型 K、int型の L、int型の R、int型のx、int型の Y、int型の L、INT R、int型のID){
         場合(X <= L && R <= Y){
             セット <ペア< INTINT >> :それをイテレータ。
            一方、(!S [k]は.empty()){  S = [K] .lower_bound(make_pair(L、 - 1 ))。
                もし(それ== S [k]は.END()||(※)1次回> R)ブレークint型の V =(*それは).second。
                もし(DIS [V]> DIS [ID]){ 
                    DIS [V] = DIS [ID]。
                    que.push(make_pair( - DIS [V]、V))。
                } S [k]は.erase( * IT)。
            } 
            を返します
        } 
        INT半ば= L + R >> 1 もし(x <= MID)クエリ(K << 1 、L、中、X、Y、L、R、ID)。
        もし(MID <Y)クエリ(K << 1 | 1、中間+ 1 、R、X、Y、L、R、ID)。
        返します
    } 
}セグメント。
int型N、M、H、W。
構造体ノード{
     int型、U、V、NEX。
} X [MAXN << 1 ]。
構造体のSpe {
     intは、であり、L、R、D、W、U。
} [MAXN] F。
ボイド追加(INT U、INT V){ 
    X [CNT] .U = U、X [CNT] .V = V、X [CNT] .nex =頭部[U]、ヘッド[U]は= CNT ++ 
} 
int型のmain(){ 
    freopenは(" jump.in "" R " 、STDIN)。
    freopenは(" jump.out "" W " 、STDOUT)。 
    のmemset(頭、 -1はsizeof (ヘッド))。
    N =読み取る()、M =(読み取り)、read()は= W、H = 読み出します()。
    以下のためにint型 iは= 1 ; iが<= N; iが++)G [i]は.X読み取り=()、G [i]は.Y =(読み取り)、(segment.modify 11 [i]は、G、Wは.X、G [i]は.X、I)。
    int型 iは= 1 [I] .be = read()は、F [i]はfを.W、[I] .L =(読み取り)は、F I [F)(読み取る。=; I <= M I ++)は] .R F [i]が.Uは= F [i]が.D =リード()、read()は。= (F [i]が.be、I)を追加)(読み取ります。
    memset(DIS、127 / 3はsizeof (DIS))。
    DIS [ 1 ] = 0 ; que.push(make_pair(01));
    一方、(!que.empty()){
         int型 XX = que.pop();第二que.top()。
        もし(VIS [XX])続けます
        VIS [XX] = 1 もし(XX> N){ 
            segment.Query(11、W、F [XX-N] .L、F [XX-N] .R、F [XX-N] .D、F [XX- N] .U、XX)。
            続け; 
        } 
        のためのint型 [XX] I =ヘッドと、I =! - 1 ; I =のX [i]は.nex){
             int型 V = Xを[I] .V + N。
            もし(DIS [V]> DIS [XX] + F [X [i]は.V] .W){ 
                DIS [V] = DIS [XX] + F [X [i]は.V] .W。
                que.push(make_pair( - DIS [V]、V))。
            } 
        } 
    } のためのint型 I = 2 ; iが<= N; iが++)のprintf(" %d個の\ n " 、DIS [I])。
    リターン 0 ; 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/si-rui-yang/p/11226654.html