zoukankan      html  css  js  c++  java
  • POJ 2104 静态找区间第k大

     静态区间第k大的问题,往往可以利用主席树来解决

    这是主席树的第一道题

    主席树大概可以理解为在n个节点上都建立一棵线段树,但是想想会超出内存

    每一个节点保存的线段树都记录当前整段前缀区间的信息

    但是因为每次添加后一个节点,那么他除了当前节点位置需要更新之外,其他的位置都可以保持跟上一棵节点对应的线段树一致,那么为了缩小内存,

    将那些不需要改变的点的指针指向上一棵树对应的节点即可,其他多生成的节点也就是需要更新的节点,最多不超过log2n个,所以最后产生的线段树的

    点的个数大概在nlogn的大致范围内

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 using namespace std;
     6 #define N 100005
     7 #define M int m=(l+r)>>1
     8 #define LS(o) node[o].ls
     9 #define RS(o) node[o].rs
    10 
    11 int n , m , a[N] , b[N] , T[N];
    12 
    13 struct Node{
    14     int sz , ls , rs;
    15     void init(){sz=0;ls=rs=0;}
    16 }node[N*30];
    17 
    18 int tot;
    19 
    20 int build(int l , int r)
    21 {
    22     int u = tot++;
    23     node[u].init();
    24     if(l!=r){
    25         M;
    26         node[u].ls = build(l , m);
    27         node[u].rs = build(m+1 , r);
    28     }
    29     return u;
    30 }
    31 
    32 void build(int o1 , int o2 , int l , int r , int pos)
    33 {
    34     node[o2].init();
    35     node[o2].sz = node[o1].sz+1;
    36     M;
    37     if(l == r) return;
    38     if(pos<=m){
    39         node[o2].ls = tot++ , node[o2].rs = RS(o1);
    40         build(LS(o1) , LS(o2) , l , m , pos);
    41     }
    42     else {
    43         node[o2].rs = tot++ , node[o2].ls = LS(o1);
    44         build(RS(o1) , RS(o2) , m+1 , r , pos);
    45     }
    46 }
    47 
    48 int query(int o1 , int o2 , int l , int r , int k)
    49 {
    50     if(l==r) return l;
    51     M;
    52     int tmp;
    53     if((tmp=node[LS(o2)].sz - node[LS(o1)].sz)>=k) return query(LS(o1) , LS(o2) , l , m , k);
    54     else return query(RS(o1) , RS(o2) , m+1 , r , k-tmp);
    55 }
    56 
    57 int main()
    58 {
    59    // freopen("in.txt" , "r" , stdin);
    60     while(~scanf("%d%d" , &n , &m)){
    61         for(int i=1 ; i<=n ; i++)scanf("%d" , a+i);
    62         for(int i=1 ; i<=n ; i++)b[i]=a[i];
    63         sort(b+1 , b+n+1);
    64         tot = 0;
    65         T[0] = build(1 , n);
    66         for(int i=1 ; i<=n ; i++){
    67             int pos = lower_bound(b+1 , b+n+1 , a[i])-b;
    68             T[i] = tot++;
    69             build(T[i-1] , T[i] , 1 , n , pos);
    70         }
    71         while(m--){
    72             int s , t , k;
    73             scanf("%d%d%d" , &s , &t , &k);
    74             int pos = query(T[s-1] , T[t] , 1 , n , k);
    75             printf("%d
    " , b[pos]);
    76         }
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    cocos2dx Menu
    关于iOS招聘面试的一些问题
    OC画图
    iOS苹果产品简介
    iOS知识小总结
    @property的修饰参数的的解释
    IOS:UI设计之UINavigationController,NavigationBar,ToolBAR相关基础
    IOS:UI设计之UISegmentedControl相关基础
    IOS:UI设计之UISlider相关基础
    IOS:UI设计之UILable相关基础
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4762549.html
Copyright © 2011-2022 走看看