POJ 2104 K-th Number [主席树入门]【数据结构】
题目链接:http://poj.org/problem?id=2104 You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array segment. The first line of the input file contains n — the size of the array,and m — the number of questions to answer (1 <= n <= 100 000,1 <= m <= 5 000). For each question output the answer to it — the k-th number in sorted a[i…j] segment. 7 3 5 This problem has huge input,so please use c-style input(scanf,printf),or you may got time limit exceed. —————————————————————————————————————————————————————— 题目大意: 解题思路: 之前一直没有学习主席树,就是理解不了主席树, 算是明白了什么是主席树, 主席树为了保存历史版本的状态,于是在每次更新的时候都在开出一条链来代表新建出来的节点, 这样就不用每次在建一颗树了 其实主席树是一种函数式线段树 寻找
附本题代码 #pragma comment(linker,"/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long int LL;
const int INF = (~(1<<31));
const int N = 100000+7;
const double eps = 1e-7;
inline int read(){
int x=0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while('0'<=ch&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
/****************************************************/
int rt[N*20],ls[N*20],rs[N*20],sum[N*20],tot;
int n,q,ql,qr,x,a[N],b[N],sz;
void build(int &rt,int l,int r){
rt=++tot;
sum[rt]=0;
if(l==r) return ;
int m = (r+l)>>1;
build(ls[rt],l,m);
build(rs[rt],m+1,r);
}
void update(int &rt,int r,int last,int pos){
rt = ++tot;
ls[rt]=ls[last];
rs[rt]=rs[last];
sum[rt]=sum[last]+1;
if(l==r) return ;
int m = (r+l)>>1;
if(pos<=m) update(ls[rt],m,ls[last],pos);
else update(rs[rt],r,rs[last],pos);
}
int query(int ss,int tt,int k){
if(l==r)return l;
int m = (l+r)>>1;
int cnt=sum[ls[tt]]-sum[ls[ss]];
if(k<=cnt)return query(ls[ss],ls[tt],k);
else return query(rs[ss],rs[tt],k-cnt);
}
void qq(){
scanf("%d%d%d",&ql,&qr,&x);
printf("%dn",b[query(rt[ql-1],rt[qr],1,sz,x)]);
}
int main(){
while(~scanf("%d%d",&n,&q)){
for(int i=1;i<=n;i++) scanf("%d",a+i),b[i]=a[i];
sort(b+1,b+n+1);
sz=unique(b+1,b+n+1)-(b+1);
tot = 0;
build(rt[0],sz);
for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+sz+1,a[i])-b;
for(int i=1;i<=n;i++)update(rt[i],rt[i-1],a[i]);
while(q--)qq();
}
return 0;
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |