• HDU 2665 Kth number(可持续化线段树)


    Kth number

    Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 9213    Accepted Submission(s): 2868


    Problem Description
    Give you a sequence and ask you the kth big number of a inteval.
     

    Input
    The first line is the number of the test cases. 
    For each test case, the first line contain two integer n and m (n, m <= 100000), indicates the number of integers in the sequence and the number of the quaere. 
    The second line contains n integers, describe the sequence. 
    Each of following m lines contains three integers s, t, k. 
    [s, t] indicates the interval and k indicates the kth big number in interval [s, t]
     

    Output
    For each test case, output m lines. Each line contains the kth big number.
     

    Sample Input
    1 10 1 1 4 2 3 5 6 7 8 9 0 1 3 2
     

    Sample Output
    2
    这道题目网上的题解大多是划分树解法,其实求区间第K大还有一个方法就是可持久化线段树,
    这里由于给的值可能是负数,必须离散化,而且离散化之后的线段树空间可以开的更小一点
    防止内存超限
    #include <iostream>
    #include <string.h>
    #include <stdlib.h>
    #include <algorithm>
    #include <math.h>
    #include <stdio.h>
    #include <map>
    
    using namespace std;
    const int maxn=1e5;
    int rt[maxn+5];
    int ls[maxn*18+5];
    int rs[maxn*18+5];
    int sum[maxn*18+5];
    int b[maxn+5];
    int a[maxn+5];
    int n,m;
    int l,r;
    int p;
    map<int,int> m1,m2;
    void update(int &node,int l,int r,int val)
    {
        if(!node)
        {
            sum[p]=ls[p]=rs[p]=0;
            node=p;
            p++;
        }
        else
        {
            sum[p]=sum[node];ls[p]=ls[node];
            rs[p]=rs[node];node=p;
            p++;
        }
        if(l==r)
        {
            sum[node]++;
            return;
        }
        sum[node]++;
        int mid=(l+r)>>1;
        if(val<=mid) update(ls[node],l,mid,val);
        else update(rs[node],mid+1,r,val);
    }
    int query(int node1,int node2,int l,int r,int k)
    {
        if(sum[node2]-sum[node1]<k) return -1;
        if(l==r) return l;
        int mid=(l+r)>>1;
        int num=sum[ls[node2]]-sum[ls[node1]];
        if(num>=k)
            return query(ls[node1],ls[node2],l,mid,k);
        else
            return query(rs[node1],rs[node2],mid+1,r,k-num);
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        int s,e,k;
        while(t--)
        {
            l=1e9;r=0;
            m1.clear();
            m2.clear();
            scanf("%d%d",&n,&m);
            p=1;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&b[i]);
                a[i]=b[i];
            }
            sort(b+1,b+n+1);
            for(int i=1;i<=n;i++)
            {
                m1[b[i]]=i;
                m2[i]=b[i];
            }
            l=1,r=n;
            update(rt[1]=0,l,r,m1[a[1]]);
            for(int i=2;i<=n;i++)
                update(rt[i]=rt[i-1],l,r,m1[a[i]]);
            int ans;
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d%d",&s,&e,&k);
                ans=query(rt[s-1],rt[e],l,r,k);
                printf("%d
    ",m2[ans]);
            }
        }
        return 0;
    }
    



     

  • 相关阅读:
    Nova创建虚拟机的底层代码分析
    Chapter 1 Securing Your Server and Network(12):保护链接server
    c语言实现hashtable,相似C++的map和iOS的NSDictionary
    Android_Training
    Bean Validation 技术规范特性概述
    linux下串口调试工具/串口终端推荐: picocom
    Android:主题(Theme)
    oracle database 12c R1 安装文档
    python版本wifi共享工具
    iOS 6编程Cookbook(影印版)
  • 原文地址:https://www.cnblogs.com/dacc123/p/8228581.html
Copyright © 2020-2023  润新知