LuoGuP4197 Peaks

LuoGuP4197 Peaks

Peaks

Painful mentality:

high

In fact, this is a code of agricultural questions? Code is also not very clear-eyed farmer ... as long as, or well written.

A title, learned \ (kruskal \) reconstruction of the tree should be able to reconstruct one second a tree approach.

By weight combined tree structure reconstruction, after a given starting point multiplication in the reconstructed tree, as the right point of the tree is reconstructed not to drop from the bottom up,
it is possible to go directly multiplying a weight value less than or equal shallowest point, the right point of its sub-tree leaves \ (k \) big is the answer, sub-tree information \ (dfs \) sequence \ (+ \) Chairman of the tree can be.

What, you do not \ (Kruskal \) reconstruction of the tree? Do not speak here, I wanted to learn to see next.

Wrong because:

Read the wrong question ... seeking first thought let \ (k \) is small, the results did not tune out of tune for a long time.

\(Code:\)

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#define MEM(x,y) memset ( x , y , sizeof ( x ) )
#define rep(i,a,b) for (int i = (a) ; i <= (b) ; ++ i)
#define per(i,a,b) for (int i = (a) ; i >= (b) ; -- i)
#define pii pair < int , int >
#define one first
#define two second
#define rint read<int>
#define pb push_back
#define db double
#define ull unsigned long long
#define lowbit(x) ( x & ( - x ) )

using std::queue ;
using std::set ;
using std::pair ;
using std::max ;
using std::min ;
using std::priority_queue ;
using std::vector ;
using std::swap ;
using std::sort ;
using std::unique ;
using std::greater ;

template < class T >
    inline T read () {
        T x = 0 , f = 1 ; char ch = getchar () ;
        while ( ch < '0' || ch > '9' ) {
            if ( ch == '-' ) f = - 1 ;
            ch = getchar () ;
        }
       while ( ch >= '0' && ch <= '9' ) {
            x = ( x << 3 ) + ( x << 1 ) + ( ch - 48 ) ;
            ch = getchar () ;
       }
       return f * x ;
}

const int N = 1e5 + 100 ;
const int M = 5e5 + 100 ;
const int inf = 1e15 ;

struct edge {
    int to , from , data ;
    inline bool operator < (const edge & a) { return data < a.data ; }
} e[M] ;

class Chairman {
    #define mid ( ( l + r ) >> 1 )
    private :
        struct Tree { int ls , rs , data ; } t[N*40] ;
    public :
        int rt[N<<1] ;
    private :
        int crt ;
    public :
        inline void initial () { crt = 0 ; return ; }
    private :
        inline void pushup (int rt) { t[rt].data = t[t[rt].ls].data + t[t[rt].rs].data ; return ; }
    public :
        inline void insert (int & rt , int l , int r , int key) {
            t[++crt] = t[rt] ; rt = crt ;
            if ( l == r ) { ++ t[rt].data ; return ; }
            if ( key <= mid ) insert ( t[rt].ls , l , mid , key ) ;
            else insert ( t[rt].rs , mid + 1 , r , key ) ;
            pushup ( rt ) ; return ;
        }
    public:
        inline int query (int u , int v , int l , int r , int key) {
            if ( l == r ) return l ;
            int T = t[t[v].ls].data - t[t[u].ls].data ;
            if ( key <= T ) return query ( t[u].ls , t[v].ls , l , mid , key ) ;
            else return query ( t[u].rs , t[v].rs , mid + 1 , r , key - T ) ;
        }
    #undef mid
} T ; 

vector < int > G[N<<1] ;
int n , m , g[N<<1] , cnt , tot , siz[N<<1] ;
int v[N<<1] , f[25][N<<1] , deep[N<<1] , idx[N<<1] ;
int val[N<<1] , ndx , wt[N<<1] , h[N<<1] , q ;

inline void build (int u , int v , int w) {
    e[++tot].from = u ; e[tot].to = v ;
    e[tot].data = w ; return ;
}

inline int getf (int x) { return g[x] == x ? x : g[x] = getf ( g[x] ) ; }

inline void Kruskal () {
    sort ( e + 1 , e + tot + 1 ) ; cnt = n ;
    rep ( i , 1 , n << 1 ) g[i] = i ; int num = 0 ;
    rep ( i , 1 , tot ) {
        int x = getf ( e[i].from ) , y = getf ( e[i].to ) ;
        if ( x != y ) {
            ++ cnt ; v[cnt] = e[i].data ;
            g[x] = g[y] = g[cnt] = cnt ;
            G[cnt].pb ( x ) ; G[cnt].pb ( y ) ;
        }
    }
    return ;
}

inline void dfs (int cur , int anc , int dep) {
    f[0][cur] = anc ; deep[cur] = dep ; siz[cur] = 1 ;
    idx[cur] = ++ ndx ; val[ndx] = h[cur] ;
    for (int i = 1 ; ( 1 << i ) <= dep ; ++ i)
        f[i][cur] = f[i-1][f[i-1][cur]] ;
    for (int k : G[cur] ) {
        if ( k == anc ) continue ;
        dfs ( k , cur , dep + 1 ) ;
        siz[cur] += siz[k] ;
    }
    return ;
}

inline int getp (int x , int key) {
    int k = log2 ( deep[x] ) + 1 ;
    for (int i = k ; i >= 0 ; -- i)
        if ( v[f[i][x]] <= key && f[i][x] != 0 )
            x = f[i][x] ;
    return x ;
}

signed main (int argc , char * argv[]) {
    n = rint () ; m = rint () ; q = rint () ;
    rep ( i , 1 , n << 1 ) h[i] = - inf ; rep ( i , 1 , n ) h[i] = rint () ;
    rep ( i , 1 , m ) { int u = rint () , v = rint () , w = rint () ; build ( u , v , w ) ; }
    Kruskal () ; dfs ( cnt , 0 , 1 ) ;
    T.initial () ; rep ( i , 1 , ndx ) wt[i] = val[i] ;
    sort ( wt + 1 , wt + ndx + 1 ) ; wt[0] = unique ( wt + 1 , wt + ndx + 1 ) - wt - 1 ;
    rep ( i , 1 , ndx ) val[i] = std::lower_bound ( wt + 1 , wt + wt[0] + 1 , val[i] ) - wt ;
    T.rt[0] = 0 ; rep ( i , 1 , ndx ) { T.rt[i] = T.rt[i-1] ; T.insert ( T.rt[i] , 1 , wt[0] , val[i] ) ; }
    while ( q -- ) {
        int p = rint () , x = rint () , k = rint () ;
        int root = getp ( p , x ) ;
        int l = idx[root] , r = idx[root] + siz[root] - 1 ;
        int pos = T.query ( T.rt[l-1] , T.rt[r] , 1 , wt[0] , r - l + 1 - k + 1 ) ;
        if ( wt[pos] != - inf ) printf ("%lld\n" , wt[pos] , pos ) ;
        else puts ("-1") ;
    }
    system ("pause") ; return 0 ;
}

Guess you like

Origin www.cnblogs.com/Equinox-Flower/p/11683711.html