您的位置:首页 > 其它

POJ2104:K-th Number

2017-01-10 09:20 316 查看
题目链接

区间第K大。主席树的入门题。网上dalao们讲的挺清楚的,就不赘述啦、

【代码】

#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#define N 100005
#define M 8000005
#define INF 1e9
#define mod 1000000007
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pa;

int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}

int n,m,tot,cnt;
int a
,num
,hash
;
int ls[M],rs[M],sz[M],root
;

int Find(int x)
{
int l=1,r=tot,rtn;
while(l<=r)
{
int mid=l+r>>1;
if(hash[mid]>=x) rtn=mid,r=mid-1;
else l=mid+1;
}
return rtn;
}

void Insert(int l,int r,int x,int &y,int z)
{
y=++cnt;
sz[y]=sz[x]+1;
if(l==r) return;
ls[y]=ls[x];rs[y]=rs[x];
int mid=l+r>>1;
if(z<=mid) Insert(l,mid,ls[x],ls[y],z);
else Insert(mid+1,r,rs[x],rs[y],z);
}

int Ask(int l,int r,int x,int y,int k)
{
if(l==r) return l;
int mid=l+r>>1;
if(sz[ls[y]]-sz[ls[x]]>=k) return Ask(l,mid,ls[x],ls[y],k);
return Ask(mid+1,r,rs[x],rs[y],k-sz[ls[y]]+sz[ls[x]]);
}

int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++) num[i]=a[i]=read();
sort(num+1,num+1+n);
hash[++tot]=num[1];
for(int i=2;i<=n;i++)
if(num[i]!=num[i-1]) hash[++tot]=num[i];
for(int i=1;i<=n;i++) Insert(1,tot,root[i-1],root[i],Find(a[i]));
for(int i=1;i<=m;i++)
{
static int x,y,z;
x=read(),y=read(),z=read();
printf("%d\n",hash[Ask(1,tot,root[x-1],root[y],z)]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: