POJ2104 K-th Number 划分树 模板题啊

本文提供了一道编号为2104的编程题的解答思路及实现代码,使用G++语言通过构建树状结构来解决区间查询问题,具体涉及数值排序、区间划分等算法。
/*Source Code
Problem: 2104        User: 96655
Memory: 14808K        Time: 1282MS
Language: G++        Result: Accepted
Source Code*/

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<stack>
using namespace std;
const int maxn=100005;
struct node
{
    int val[maxn],num[maxn];
};
struct Tree
{
    int n,o[maxn];
    node t[20];
    void init(int len)
    {
        n=len;
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&o[i]);
            t[0].val[i]=o[i];
        }
        sort(o+1,o+n+1);
        build(1,n,0);
    }
    void build(int l,int r,int dep)
    {
        if(l==r)return;
        int m=(l+r)>>1;
        int lsame=m-l+1,same=0,ln=l,rn=m+1;
        for(int i=l; i<=r; i++)
            if(t[dep].val[i]<o[m])--lsame;
        for(int i=l; i<=r; i++)
        {
            if(i==l)t[dep].num[i]=0;
            else t[dep].num[i]+=t[dep].num[i-1];
            if(t[dep].val[i]<o[m])
                ++t[dep].num[i],t[dep+1].val[ln++]=t[dep].val[i];
            else if(t[dep].val[i]>o[m])
                t[dep+1].val[rn++]=t[dep].val[i];
            else
            {
                ++same;
                {
                    if(lsame>=same)
                        ++t[dep].num[i],t[dep+1].val[ln++]=t[dep].val[i];
                    else t[dep+1].val[rn++]=t[dep].val[i];
                }
            }
        }
        build(l,m,dep+1);
        build(m+1,r,dep+1);
    }
    int query(int st,int ed,int k,int l,int r,int dep)
    {
        if(l==r)return t[dep].val[l];
        int lx,ly,rx,ry,m=(l+r)>>1;
        if(st==l)lx=0;
        else lx=t[dep].num[st-1];
        ly=t[dep].num[ed];
        if(ly-lx>=k)
            return query(l+lx,l+ly-1,k,l,m,dep+1);
        else
        {
            rx=st-l-lx;
            ry=ed-st+1-(ly-lx);
            return query(m+1+rx,m+rx+ry,k-(ly-lx),m+1,r,dep+1);
        }
    }
}tree;
int main()
{
    int n,q;
    while(~scanf("%d%d",&n,&q))
    {
       tree.init(n);
       while(q--)
       {
           int l,r,k;
           scanf("%d%d%d",&l,&r,&k);
           int ans=tree.query(l,r,k,1,n,0);
           printf("%d\n",ans);
       }
    }
    return 0;
}
View Code

 num数组一定要初始化,但是不知为什么POJ没初始化就过了,HDU同样的题就必须初始化,反正加上初始化没有错

转载于:https://www.cnblogs.com/shuguangzw/p/4937646.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值