zoukankan      html  css  js  c++  java
  • HDU 2665 Kth number

    题解:求区间K小,函数式线段树模板题。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=3000005;
    struct node{int num,id;}a[N];
    int T,n,m,x,y,z,tot,b[N],head[N],son[N][2],data[N];
    int cmp(node a,node b){return a.num<b.num;}
    int make(int l,int r){
        int t=++tot,mid=(l+r)>>1;
        if(l==r)return t;
        son[t][0]=make(l,mid);son[t][0]=make(mid+1,r);
        return t;
    }
    int insert(int x,int pos,int l,int r){
        int t=++tot,mid=(l+r)>>1;
        data[t]=data[pos]+1;
        if(l==r)return t;
        if(x<=mid)son[t][1]=son[pos][1],son[t][0]=insert(x,son[pos][0],l,mid);
        else{son[t][0]=son[pos][0];son[t][1]=insert(x,son[pos][1],mid+1,r);}
        return t;
    } 
    int ask(int x,int y,int k,int l,int r){
        int mid=(l+r)>>1;
        if(l==r)return l;
        int rk=data[son[y][0]]-data[son[x][0]];
        if(k<=rk)return ask(son[x][0],son[y][0],k,l,mid);
        else return ask(son[x][1],son[y][1],k-rk,mid+1,r);
    }
    int main(){
        scanf("%d",&T);
        while(T--){
            tot=0;
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++){scanf("%d",&a[i].num);a[i].id=i;}
            sort(a+1,a+n+1,cmp);
            for(int i=1;i<=n;i++)b[a[i].id]=i;
            head[0]=make(1,n);
            for(int i=1;i<=n;i++)head[i]=insert(b[i],head[i-1],1,n);
            for(int i=1;i<=m;i++){
                scanf("%d%d%d",&x,&y,&z);
                if(x>y)swap(x,y);
                printf("%d
    ",a[ask(head[x-1],head[y],z,1,n)].num);
            }
        }return 0;
    }
    
  • 相关阅读:
    1. 命令执行漏洞简介
    3. 从零开始学CSRF
    2. DVWA亲测CSRF漏洞
    使用pt-fifo-split 工具往mysql插入海量数据
    如何打印矩阵
    年轻人,你活着不是为了观察K线做布朗运动
    Python 之匿名函数和偏函数
    Python之闭包
    Python之装饰器
    Python之with语句
  • 原文地址:https://www.cnblogs.com/forever97/p/3937157.html
Copyright © 2011-2022 走看看