zoukankan      html  css  js  c++  java
  • POJ2104 K-th Number(线段树,二分,vector)

    题意

    不带修改区间第k小。(n<=100000)

    题解

    建立线段数和vector数组(vector为当前区间排列之后的序列)(归并)

    然后对于每一个询问二分答案。

    问题就转化为区间有多少数小于等于二分值。

    对于我们每一个遍历的区间(线段数的节点)。

    若与询问区间不相交return0。

    若完全包含于询问区间则在此区间的vector上二分查找有多少数小于二分值(因为已经排好序,所以很好做)

    若有相交部分则继续遍历子树。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<vector>
     7 using namespace std;
     8 const int N=100010;
     9 vector<int> d[N*5];
    10 struct tree{
    11     int l,r;
    12 }tr[N*8];
    13 const int INF=1000000007;
    14 int a[N*2];
    15 int n,m;
    16 void build(int l,int r,int now){
    17     tr[now].l=l;tr[now].r=r;
    18     if(l==r){
    19         d[now].push_back(-INF);
    20         d[now].push_back(a[l]);
    21         return;
    22     }
    23     int mid=(l+r)>>1;
    24     build(l,mid,now*2);
    25     build(mid+1,r,now*2+1);
    26     int size1=d[now*2].size()-1;
    27     int size2=d[now*2+1].size()-1;
    28     int i=1,j=1;
    29     d[now].push_back(-INF);
    30     while(i<=size1&&j<=size2){
    31         if(d[now*2][i]>d[now*2+1][j])d[now].push_back(d[now*2+1][j++]);
    32         else d[now].push_back(d[now*2][i++]);
    33     }
    34     while(i<=size1)d[now].push_back(d[now*2][i++]);
    35     while(j<=size2)d[now].push_back(d[now*2+1][j++]);
    36     return;
    37 }
    38 int getnum(int now,int K){
    39     int x=1;int y=d[now].size()-1;
    40     int tmp=0;
    41     while(x<=y){
    42         int mid=(x+y)>>1;
    43     //    cout<<x<<" "<<y<<endl;
    44         if(d[now][mid]<=K){
    45             tmp=mid;
    46             x=mid+1;
    47         }
    48         else y=mid-1;
    49     }
    50     return tmp;
    51 }
    52 int check(int l,int r,int now,int K){
    53 //    cout<<l<<" "<<r<<endl;
    54     if(tr[now].l>r||tr[now].r<l)return 0;
    55     if(l<=tr[now].l&&tr[now].r<=r){
    56     //    cout<<l<<" "<<r<<" "<<getnum(now,K)<<endl;
    57         return getnum(now,K);
    58     }
    59     int mid=(tr[now].l+tr[now].r)>>1;
    60     int tmp1=check(l,r,now*2,K);
    61     int tmp2=check(l,r,now*2+1,K);
    62     return tmp1+tmp2; 
    63 }
    64 int search(int l,int r,int k){
    65     int tmp;
    66     int x=-INF;
    67     int y=INF;
    68     while(x<=y){
    69         int mid=(x+y)>>1;
    70         int num=check(l,r,1,mid);
    71     //    cout<<mid<<" "<<num<<endl;
    72         if(num>=k){
    73             tmp=mid;
    74             y=mid-1;
    75         }
    76         else x=mid+1;
    77     }
    78     return tmp;
    79 }
    80 int main(){
    81     scanf("%d%d",&n,&m);
    82     for(int i=1;i<=n;i++){
    83         scanf("%d",&a[i]);
    84     }
    85     build(1,n,1);
    86     for(int i=1;i<=m;i++){
    87         int l,r,k;
    88         scanf("%d%d%d",&l,&r,&k);
    89         int ans=search(l,r,k);
    90         printf("%d
    ",ans);
    91     }
    92     return 0;
    93 }
    View Code
  • 相关阅读:
    微信小程序 选择图片 并上传到服务器
    微信小程序 setData
    python--字典排序
    python--csv文件读写
    机器学习实战笔记--AdaBoost(实例代码)
    机器学习实战笔记--朴素贝叶斯(实例代码)
    python继承 super()
    机器学习实战笔记—决策树(代码讲解)
    java的基本认识
    Delphi制作DLL
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9392549.html
Copyright © 2011-2022 走看看