您的位置:首页 > 其它

poj 2104 K-th Number(可持久线段树)

2014-08-22 01:40 337 查看
K-th Number

持久化:/article/5883285.html

结构:http://www.docin.com/p-627462377.html

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 100010;
int n, m, tot;
int a
, x
, xcnt;
int T[N*20], ls[N*20], rs[N*20], sum[N*20];

void build(int l, int r ,int &rt)
{
rt=++tot;
sum[rt]=0;
if(l==r) return ;
int m=(l+r)>>1;
build(l, m, ls[rt]);
build(m+1,r,rs[rt]);
}

void update(int last, int p, int l, int r, int &rt)
{
rt = ++tot;
ls[rt]=ls[last], rs[rt]=rs[last], sum[rt]=sum[last]+1;
if(l==r) return ;
int m = (l+r)>>1;
if(p<=m) update(ls[last], p, l, m, ls[rt]);
else update(rs[last], p, m+1, r, rs[rt]);
}

int query(int ss, int tt, int l, int r, int k)
{
if(l==r) return l;
int m = (l+r)>>1;
int num = sum[ls[tt]] - sum[ls[ss]];
if(k<=num) return query(ls[ss], ls[tt], l, m, k);
else return query(rs[ss], rs[tt], m+1, r, k-num);
return 0;
}

void solve()
{
tot = 0;
for(int i=1; i<=n; i++)
{
scanf("%d", &a[i]);
x[i] = a[i];
}
sort(x+1, x+n+1);
xcnt = unique(x+1, x+1+n)-x-1;
for(int i=1; i<=n; i++) a[i] = lower_bound(x+1, x+n+1, a[i])-x;
build(1, xcnt, T[0]);
for(int i=1; i<=n; i++) update(T[i-1],a[i],1,xcnt,T[i]);
int l, r, k;
while(m--)
{
scanf("%d%d%d", &l, &r, &k);
printf("%d\n", x[query(T[l-1],T[r],1,xcnt,k)]);
}
}

int main()
{
while(scanf("%d%d", &n, &m)>0 ) solve();
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: