後続のリングセグメントツリーを求め--cf1237D +

/ * 
見つけるために次のセグメントツリーで、評価降順トリプルアークを開く第一のリング(2回十分ではない)、
/ * 
の#include <ビット/ STDC ++ H.>
 使用して 名前空間STDと、
 の#define N 300005 INT N-、A [N]、ANS [N]; の#define LSONのL、M、RT << 1。
 の#define rson 1 + M、R&LT、RT 1 << | 1。。。
 INT最大[N << 2 ]、最小[N << 2 ]、POS1、POS2、
 空洞ビルド(int型 L、int型の R&LT、int型RT)を{ 
    マックス[RT] = 0 ;最小[RT] = 1E9 + 7。;
     IF(L == R&LT){ 
        マックス[RT] =最小[RT ] = A [L]。
        



返す; 
    } 
    int型の M = L + R&LT >> 1 ; 
    (rson)ビルド;ビルド(LSON)を
    最大[RT] = MAX(最大[RT << 1。 ]、最大[RT << 1。 | 1。]); 
    分[RT] =分(分[RT << 1。 ]、分[RT << 1。 | 1。]); 
} 
ボイド Query1を(int型 L、INT R&LT、int型 V、INTを L、INT R&LT、INT RT){ // Vは、後継者を見つけるために、最初のより大きい
    IF(L == R&LT){
         IF(最大[RT]> V)= POS1分(POS1、L)。
        返します
    } 
    INT M = 1 + rを>> 1 もし(L <= 1 && R> = R){ // 可以在区间里二分了
        する場合(最大[RT << 1 ]> V)
            Query1を(L、R、V、LSON)。
        他の 場合(最大[RT << 1 | 1 ]> V)
            Query1を(L、R、V、rson)。
        返します
    } 
    場合(L <= M)Query1を(L、R、V、LSON)。
    もし(R> M)Query1を(L、R、V、rson)。
} 
ボイド QUERY2(int型 L、int型の R、ダブルV、INTを L、int型の R、int型 RT){ // 找第一个比V小的后继
    場合(L == R){
         場合(最小[RT] <V)POS2 = 分(POS2、L)。
        返します
    } 
    INT M = 1 + rを>> 1 もし(L <= 1 && R> = R){
         場合(最小[RT << 1 ] < V)
            QUERY2(L、R、V、LSON)。
        そう であれば(最小[RT << 1 | 1 ] < V)
            QUERY2(L、R、V、rson)。
        返します
    } 
    場合(L <=M)QUERY2(L、R、V、LSON)。
    もし(R> M)QUERY2(L、R、V、rson)。
} 

int型のmain(){ 
    CIN >> N。
    int型のmx = 0、MI = 0x3f3f3f3f 以下のためにint型 i = 1 ; iが<= N; iは++ ){ 
        CIN >> [I]。
        A [iが N +] [I + = 2 * nを] = [I]。
        MX = MAX(MX、[I])。
        MI = 分(MI、[I])。
    } 
    
    であれば(MX <= MI * 2 ){
         ためINTi = 1 ; iは= <N; iは++)COUT << - 1 << "  " リターン 0 ; 
    } 
    
    ビルド(13 * nを、1 ); 
    ANS [ 3 *のN] = 1 以下のためにint型 I = 3 * N- 1、I> = 1 ; i-- ){ 
        POS1 = POS2 = 3 * N + 1 
        Query1を(I + 12 * nを、[i]は、13 * nを、1); // 最初の[i]が位置よりも大きい見つける 
        QUERY2の(I +は13。 * N-、1.0 * [I] / 213。 * n-は、1。); // 最初未満を見つけます位置[I] / 2 
        IF(POS1 == 3。 * N-+ 1。 && == POS2 3。 * N-+ 1// 以降可能である 
            ANSは、[I] = 3。 * -n-I + 1 ; 
          IF(POS1 == 。3 * + N- 1// バック超えない[i]が大きい 
            ANS [I] = pos2- I。 
        他の IF(POS2 == 3。 * N-+ 1。 // バックを超えない[I] / 2小さな 
            ANS [I] = ANS [POS1] + pos1- 私は、
         他の IF(POS1 <POS2)// 大で小さなフロント 
            ANS [I] = ANS [POS1] + pos1- I;
          IF(POS1> POS2)
            ANS [I] = pos2- I; 
    } 
    ためINT I = 1。 ; <= N-I; I ++は
        COUT < <ANS [I] << "  " ; 
}

 

おすすめ

転載: www.cnblogs.com/zsben991126/p/11727773.html