Seeking subsequent ring segment tree --cf1237D +

/*
First, eliminate open-loop three times (twice is not enough), reverse evaluation, tree line to find what the successor 
*/
#include<bits/stdc++.h>
using namespace std;
#define N 300005

int n, a [N] years [N];

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int Max[N<<2],Min[N<<2],pos1,pos2;
void build(int l,int r,int rt){
    Max[rt]=0;Min[rt]=1e9+7;
    if(l==r){
        Max[rt]=Min[rt]=a[l];
        return;
    }
    int m=l+r>>1;
    build(lson);build(rson);
    Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
    My [rt] = min (My [rt << 1 ], My [rt << 1 | 1 ]);
}
void Query1 ( int L, int R & lt, int v, int L, int R & lt, int RT) { // find greater than a first successor of v 
    IF (L == R & lt) {
         IF (Max [RT]> v) = POS1 min (POS1, L);
         return ;
    } 
    int m = L + R & lt >> . 1 ;
     IF (L <= R & lt && L> = R & lt) { // can be divided in two sections where 
        IF (Max [RT << . 1 ]> V)
            query1(L,R,v,lson);
        else if(Max[rt<<1|1]>v)
            query1 (L, R, v, rson);
        return;
    }
    if(L<=m)query1(L,R,v,lson);
    if(R>m)query1(L,R,v,rson); 
}
void of query2 ( int L, int R & lt, Double v, int L, int R & lt, int RT) { // find the first successor of v smaller than 
    IF (L == R & lt) {
         IF (Min [RT] <v) = POS2 min (POS2, L);
         return ;
    }
    int m=l+r>>1;
    if(L<=l && R>=r){
        if(Min[rt<<1]<v)
            query2 (L, R, v, lson);
        else if(Min[rt<<1|1]<v)
            query2 (L, R, v, rson);
        return;
    }
    if(L<=m)query2(L,R,v,lson);
    if(R>m)query2(L,R,v,rson);
} 

int main () {
    cin>>n;
    int mx=0,mi=0x3f3f3f3f;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        a[i+n]=a[i+2*n]=a[i];
        mx=max(mx,a[i]);
        mL = min (mi, [i]);
    }
    
    if(mx<=mi*2){
        for(int i=1;i<=n;i++)cout<<-1<<" ";
        return 0;
    }
    
    build(1,3*n,1);
    ans[3*n]=1;
    for(int i=3*n-1;i>=1;i--){
        pos1=pos2=3*n+1;
        Query1 (I + . 1 , 2 * n-, a [i], . 1 , . 3 * n-, . 1 ); // find the first is greater than a [i] position 
        of query2 (I + . 1 , . 3 * n-, 1.0 * A [ I] / 2 , . 1 , . 3 * n-, . 1 ); // find the first less than a [i location] / 2 
        IF (POS1 == . 3 * n-+ . 1 && == POS2 . 3 * n-+ . 1 ) // later are feasible 
            ANS [I] = . 3 *-n-I + . 1 ; 
         the else  IF(POS1 == . 3 * n-+ . 1 ) // behind no greater than A [i] 
            ANS [i] = pos2- I; 
         the else  IF (POS2 == . 3 * n-+ . 1 ) // behind no [i] ratio a / 2 small 
            ANS [I] = ANS [POS1] + pos1- I;
         the else  IF (POS1 <POS2) // large in a small front 
            ANS [I] = ANS [POS1] + pos1- I;
         the else  IF (POS1 > pos2)
            ans[i]=pos2-i; 
    }
    for(int i=1;i<=n;i++)
        cout<<ans[i]<<" ";
} 

 

Guess you like

Origin www.cnblogs.com/zsben991126/p/11727773.html