LuoGuP4197 Peaks

懵懂的女人 提交于 2019-12-01 11:43:36

LuoGuP4197 Peaks

Peak

痛苦的心路:

其实这是个码农题?也不算很码农...只要头脑清晰,还是很好写的.

一眼题,学过 \(kruskal\) 重构树的人应该能一眼秒出重构树的做法.

按权值合并,构造重构树,给定起点后在重构树上倍增,因为重构树的点权是自底向上不降的,
所以可以直接倍增去找权值小于等于某个值的深度最浅的点,它的子树中的叶子的点权的第 \(k\) 大就是答案,子树信息用 \(dfs\)\(+\) 主席树即可.

什么,你不会 \(Kruskal\) 重构树?这里不讲,想学去看下一篇.

错因:

读错题了...以为让求第 \(k\) 小,结果调了半天没调出来.

\(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 ; }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!