zoukankan      html  css  js  c++  java
  • POJ2104 K-th Number 不带修改的主席树 线段树

    http://poj.org/problem?id=2104

    给定一个序列,求区间第k小

    通过构建可持久化的点,得到线段树左儿子和右儿子的前缀和(前缀是这个序列从左到右意义上的),然后是一个二分的get操作。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #define LL long long
     7 const LL maxn=100010;
     8 using namespace std;
     9 int n,m;
    10 struct node{
    11     int lc,rc,sum;
    12 }t[maxn*20];int tot;
    13 struct nod{
    14     int x,id;
    15 }a[maxn];
    16 int rk[maxn]={},rt[maxn]={};
    17 bool mcmp(nod aa,nod bb){return aa.x<bb.x;}
    18 void insert(int &x,int l,int r,int num){
    19     t[++tot]=t[x]; ++t[tot].sum;x=tot;//cout<<t[x].sum<<endl;
    20     if(l==r)return;
    21     int mid=(r+l)/2;
    22     if(num<=mid)insert(t[x].lc,l,mid,num);
    23     else insert(t[x].rc,mid+1,r,num);
    24 }
    25 int getit(int x,int y,int k,int l,int r){
    26     if(l==r)return l;
    27     int z=t[t[y].lc].sum-t[t[x].lc].sum;
    28     int mid=(r+l)/2;
    29     if(k<=z)return getit(t[x].lc,t[y].lc,k,l,mid);
    30     else return getit(t[x].rc,t[y].rc,k-z,mid+1,r);
    31 }
    32 int main(){
    33     while(~scanf("%d%d",&n,&m)){
    34         tot=0;
    35         for(int i=1;i<=n;i++){scanf("%d",&a[i].x);a[i].id=i;}
    36         sort(a+1,a+1+n,mcmp);
    37         for(int i=1;i<=n;i++) rk[a[i].id]=i; 
    38         for(int i=1;i<=n;i++){rt[i]=rt[i-1]; insert(rt[i],1,n,rk[i]);}
    39         int x,y,k;
    40         for(int i=1;i<=m;i++){
    41             scanf("%d%d%d",&x,&y,&k);
    42             printf("%d
    ",a[getit(rt[x-1],rt[y],k,1,n)].x);
    43         }
    44     }
    45     return 0;
    46 }
    View Code

  • 相关阅读:
    解决shiro多次从redis读取session的问题
    软件测试其他方法
    异常HTTP Status 500
    支付
    java面试
    SQL入门
    软件测试理论基础
    软件测试学习第一章
    Linux在终端命令行模式下智能补全功能以及组合键
    Linux安装
  • 原文地址:https://www.cnblogs.com/137shoebills/p/8710192.html
Copyright © 2011-2022 走看看