求助:MLE k-dtree求调

P4148 简单题

灵华 @ 2022-04-28 15:17:34

为啥这种写法的空间开销这么大啊,感觉好像不是特别大才对吧/kk/kk/kk

路过大佬能不能帮忙看看

#include <iostream>
#include <algorithm>
using namespace std ;

inline int read ( ) {
    char ch = getchar ( ) ;
    int x = 0 ;
    while ( ch < '0' || ch > '9' )
        ch = getchar ( ) ;
    while ( ch >= '0' && ch <= '9' )
        x = x * 10 + ch - 48 , ch = getchar ( ) ;
    return x ;
}

const int N = 200005 , K = 2 ;
const double A = 0.75 ;
int n , rt , tot , p[K][N] , val[N] , tax[K][N] , tin[K][N] , pax[K] , pin[K] ;
int dt , g[N] , d[N] , siz[N] , sum[N] , ls[N] , rs[N] , lans ;

int D ;
inline bool cmp ( int u , int v ) {
    return p [ D ] [ u ] < p [ D ] [ v ] ;
}

inline bool comp ( int x , int y ) {
    return x > y ;
}

void pushup ( int k ) {
    siz [ k ] = siz [ ls [ k ] ] + siz [ rs [ k ] ] + 1 ;
    sum [ k ] = sum [ ls [ k ] ] + sum [ rs [ k ] ] + val [ k ] ;
    for ( int i = 0 ; i < K ; ++ i )
        tin [ i ] [ k ] = tax [ i ] [ k ] = p [ i ] [ k ] ;
    if ( ls [ k ] ) {
        for ( int i = 0 ; i < K ; ++ i )
            tin [ i ] [ k ] = min ( tin [ i ] [ k ] , tin [ i ] [ ls [ k ] ] ) ,
            tax [ i ] [ k ] = max ( tax [ i ] [ k ] , tax [ i ] [ ls [ k ] ] ) ;
    }
    else {
        for ( int i = 0 ; i < K ; ++ i )
            tin [ i ] [ k ] = min ( tin [ i ] [ k ] , tin [ i ] [ rs [ k ] ] ) ,
            tax [ i ] [ k ] = max ( tax [ i ] [ k ] , tax [ i ] [ rs [ k ] ] ) ;
    }
}

int build ( int l , int r ) {
    if ( l > r ) return 0 ;
    int mid = ( l + r ) >> 1 ;
    double a[K] , b[K] , axx = 0 ;
    for ( int i = 0 ; i < K ; ++ i ) a [ i ] = 0 ;
    for ( int i = l ; i <= r ; ++ i )
        for ( int j = 0 ; j < K ; ++ j )
            a [ j ] += p [ j ] [ g [ i ] ] ;
    for ( int i = 0 ; i < K ; ++ i )
        a [ i ] /= 1.0 * ( r - l + 1 ) ;
    for ( int i = l ; i <= r ; ++ i )
        for ( int j = 0 ; j < K ; ++ j )
            b [ j ] += ( p [ j ] [ g [ i ] ] - a [ j ] ) * ( p [ j ] [ g [ i ] ] - a [ j ] ) ;
    for ( int i = 0 ; i < K ; ++ i )
        if ( b [ i ] > axx )
            D = i , axx = b [ i ] ;
    nth_element ( g + 1 , g + mid , g + r + 1 , cmp ) ;
    d [ g [ mid ] ] = D ;
    ls [ g [ mid ] ] = build ( l , mid - 1 ) ;
    rs [ g [ mid ] ] = build ( mid + 1 , r ) ;
    pushup ( g [ mid ] ) ;
    return g [ mid ] ;
}

void dfs ( int k ) {
    if ( ! k ) return ;
    dfs ( ls [ k ] ) ;
    g [ ++ dt ] = k ;
    dfs ( rs [ k ] ) ;
}

void rebuild ( int &k ) {
    dt = 0 ;
    dfs ( k ) ;
    k = build ( 1 , dt ) ;
}

inline bool Bad ( int k ) {
    return A * siz [ k ] <= ( double ) max ( siz [ ls [ k ] ] , siz [ rs [ k ] ] ) ;
}

void insert ( int &k , int v ) {
    if ( ! k ) {
        k = v ;
        pushup ( k ) ;
        return ;
    }
    if ( p [ d [ k ] ] [ v ] <= p [ d [ k ] ] [ k ] )
        insert ( ls [ k ] , v ) ;
    else insert ( rs [ k ] , v ) ;
    pushup ( k ) ;
    if ( Bad ( k ) ) rebuild ( k ) ;
}

inline bool out ( int k ) {
    for ( int i = 0 ; i < K ; ++ i )
        if ( tin [ i ] [ k ] > pax [ i ] || tax [ i ] [ k ] < pin [ i ] )
            return 1 ;
    return 0 ;
}

inline bool in ( int k ) {
    for ( int i = 0 ; i < K ; ++ i )
        if ( tin [ i ] [ k ] > pin [ i ] || tax [ i ] [ k ] < pax [ i ] )
            return 0 ;
    return 1 ;
}

int query ( int k ) {
    if ( ! k || out ( k ) ) return 0 ;
    if ( in ( k ) ) return sum [ k ] ;
    int ret = 1 ;
    for ( int i = 0 ; i < K ; ++ i )
        if ( p [ i ] [ k ] < pin [ i ] || p [ i ] [ k ] > pax [ i ] )
            ret = 0 ;
    return query ( ls [ k ] ) + query ( rs [ k ] ) + ret * val [ k ] ;
}

int main ( ) {
    n = read ( ) ;
    while ( 1 ) {
        int opt = read ( ) ;
        if ( opt == 3 ) break ;
        if ( opt == 1 ) {
            ++ tot ;
            for ( int i = 0 ; i < K ; ++ i )
                p [ i ] [ tot ] = read ( ) ^ lans ;
            val [ tot ] = read ( ) ^ lans ;
            insert ( rt , tot ) ;
        }
        else {
            for ( int i = 0 ; i < K ; ++ i )
                pin [ i ] = read ( ) ^ lans ;
            for ( int i = 0 ; i < K ; ++ i ) {
                pax [ i ] = read ( ) ^ lans ;
                if ( pin [ i ] > pax [ i ] )
                    swap ( pin [ i ] , pax [ i ] ) ;
            }
            lans = query ( rt ) ;
            cout << lans << "\n" ;
        }
    }
    return 0 ;
}

by qsceszthn @ 2022-04-28 20:23:30

马蜂好恐怖


|