zoukankan      html  css  js  c++  java
  • bzoj 2770 堆的中序遍历性质

    我们知道二叉搜索树的中序遍历是一个已经排好序的序列,知道序列我们无法确定树的形态(因为有多种)。

    但是,Treap如果告诉我们它的关键字以及权值,那么就可以唯一确定树的形态(Treap的O(logn)的期望时间复杂度就是依靠一个随机堆的深度不会太深)

    具体的,已知关键字序列:k1,k2,k3...kn和优先级序列:p1,p2,p3,...pn,

    如果我们想要找ki的父亲,只需要找“左边第一个p比它大的和右边第一个p比它大的中,p较小的那个“

    至于lca(ki,kj),是对应的pi~pj中的最小值(因为是小根堆)

    至于深度,多次找父亲,路径长度就是深度,然后画一下图可以发现轨迹的特点,然后就可以搞了(求两段递增子序列长度)

      1 /**************************************************************
      2     Problem: 2770
      3     User: idy002
      4     Language: C++
      5     Result: Accepted
      6     Time:6140 ms
      7     Memory:46124 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <vector>
     12 #include <algorithm>
     13 #define oo 0x6FFFFFFF
     14 #define maxn 400010
     15 using namespace std;
     16  
     17 typedef pair<int,int> dpr;
     18  
     19 struct Node {
     20     int lf, rg, mid;
     21     dpr st;
     22     bool leaf;
     23     Node *ls, *rs;
     24 } pool[maxn*3], *tail=pool, *root;
     25 vector<Node*> stk;
     26  
     27 int disc[maxn], ntot;
     28 int sv[maxn];
     29 int pr[maxn][3];
     30  
     31 Node *build( int lf, int rg ) {
     32     Node *nd = ++tail;
     33     nd->lf=lf, nd->rg=rg, nd->mid=(lf+rg)>>1;
     34     if( lf==rg ) {
     35         nd->st = dpr( oo, 0 );
     36         nd->leaf = true;
     37     } else {
     38         nd->ls = build( lf, nd->mid );
     39         nd->rs = build( nd->mid+1, rg );
     40         nd->st = dpr( oo, 0 );
     41         nd->leaf = false;
     42     }
     43     return nd;
     44 }
     45 dpr qu_min( Node *nd, int lf, int rg ) {
     46     if( lf <= nd->lf && nd->rg <= rg ) return nd->st;
     47     dpr rt = dpr( oo, 0 );
     48     if( lf <= nd->mid )
     49         rt = qu_min( nd->ls, lf, rg );
     50     if( rg > nd->mid )
     51         rt = min( rt, qu_min( nd->rs, lf, rg ) );
     52     return rt;
     53 }
     54 void pushup( Node *nd ) {
     55     nd->st = min( nd->ls->st, nd->rs->st );
     56 }
     57 void modify( Node *nd, int pos, int val ) {
     58     if( nd->leaf ) {
     59         nd->st = dpr( val, pos );
     60         return;
     61     }
     62     if( pos <= nd->mid )
     63         modify( nd->ls, pos, val );
     64     else
     65         modify( nd->rs, pos, val );
     66     pushup( nd );
     67 }
     68 int lca( int u, int v ) {
     69     if( u>v ) swap(u,v);
     70     return qu_min( root, u, v ).second;
     71 }
     72  
     73 int main() {
     74     int n, m, T;
     75     scanf( "%d%d", &n, &m );
     76     T = n+m;
     77     for( int i=1; i<=n; i++ ) {
     78         pr[i][0] = 0;
     79         scanf( "%d", pr[i]+1 );
     80         disc[++ntot] = pr[i][1];
     81     }
     82     for( int i=1; i<=n; i++ )
     83         scanf( "%d", pr[i]+2 );
     84     for( int i=n+1; i<=T; i++ ) {
     85         char opt[10];
     86         scanf( "%s", opt );
     87         pr[i][0] = opt[0]=='I' ? 0 :
     88                    opt[0]=='D' ? 1 : 2;
     89         if( pr[i][0]==0 ) {
     90             scanf( "%d%d", pr[i]+1, pr[i]+2 );
     91             disc[++ntot] = pr[i][1];
     92         } else if( pr[i][0]==1 ) {
     93             scanf( "%d", pr[i]+1 );
     94         } else {
     95             scanf( "%d%d", pr[i]+1, pr[i]+2 );
     96         }
     97     }
     98     sort( disc+1, disc+1+ntot );
     99     ntot = unique( disc+1, disc+1+ntot ) - disc - 1;
    100     for( int i=1; i<=T; i++ ) {
    101         pr[i][1] = lower_bound( disc+1, disc+1+ntot, pr[i][1] )-disc;
    102         if( pr[i][0]==2 )
    103             pr[i][2] = lower_bound( disc+1, disc+1+ntot, pr[i][2] )-disc;
    104     }
    105     root = build( 1, ntot );
    106     for( int i=1; i<=T; i++ ) {
    107         if( pr[i][0]==0 ) {
    108             modify( root, pr[i][1], pr[i][2] );
    109         } else if( pr[i][0]==1 ) {
    110             modify( root, pr[i][1], oo );
    111         } else {
    112             int u = pr[i][1];
    113             int v = pr[i][2];
    114             printf( "%d
    ", disc[lca(u,v)] );
    115         }
    116     }
    117 }
    View Code
  • 相关阅读:
    代码块;继承;this与super关系;重载与重写对比;类的继承特点;final关键字 (Java Day08)
    变量访问;this关键字;静态;工具类;帮助文档;Math使用;Arrays使用(Java Day07)
    面向对象;类和对象;访问对象;创建对象在内存中的理解;匿名对象;封装和this (Java Day06)
    如何保证 RocketMQ 不丢失消息
    Java-String类型的参数传递问题
    图解前中后序遍历
    一文彻底理解ReentrantLock可重入锁的使用
    聊聊MySQL、HBase、ES的特点和区别
    MySQL vs Java 数据类型
    Multi-Tenancy多租户模式
  • 原文地址:https://www.cnblogs.com/idy002/p/4316514.html
Copyright © 2011-2022 走看看