首页 > 代码库 > POJ 2104 求序列里第K大 主席树裸体题
POJ 2104 求序列里第K大 主席树裸体题
给定一个n的序列,有m个询问 每次询问求l-r 里面第k大的数字是什么
只有询问,没有修改
可以用归并树和划分树(我都没学过。。囧)
我是专门冲着弄主席树来的
对主席树的建树方式有点了解了,不过这题为什么是在主席树里面这么操作的 还是有点不懂,今天照着模板敲了一遍就打多校了
再研究吧
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=100010;const int maxm=maxn*30;int n,m,tot,s;int A[maxn],t[maxn],T[maxn];int c[maxm],lson[maxm],rson[maxm];int build(int l,int r){ int rt=++tot; c[rt]=0; if (l>=r) return rt; int mid=(l+r)>>1; lson[rt]=build(l,mid); rson[rt]=build(mid+1,r); return rt;}int update(int rt,int pos,int val){ int newrt=++tot,tmp=newrt; c[newrt]=c[rt]+val; int l=1,r=s; while (l<r) { int mid=(l+r)>>1; if (pos<=mid){ r=mid; lson[newrt]=++tot;rson[newrt]=rson[rt]; newrt=lson[newrt];rt=lson[rt]; } else{ l=mid+1; rson[newrt]=++tot;lson[newrt]=lson[rt]; newrt=rson[newrt];rt=rson[rt]; } c[newrt]=c[rt]+val; } return tmp;}int query(int lrt,int rrt,int k){ int l=1,r=s; while (l<r) { int mid=(l+r)>>1; if (c[lson[lrt]]-c[lson[rrt]]>=k){ r=mid; lrt=lson[lrt]; rrt=lson[rrt]; } else { l=mid+1; k-=c[lson[lrt]]-c[lson[rrt]]; lrt=rson[lrt]; rrt=rson[rrt]; } } return l;}int main(){ while (scanf("%d%d",&n,&m)!=EOF) { tot=0; for (int i=1;i<=n;i++) scanf("%d",&A[i]),t[i]=A[i]; sort(t+1,t+1+n); s=unique(t+1,t+1+n)-(t+1); T[n+1]=build(1,m); for (int i=n;i>=1;i--){ int pos=lower_bound(t+1,t+n+1,A[i])-t; T[i]=update(T[i+1],pos,1); } while (m--) { int l,r,k; scanf("%d%d%d",&l,&r,&k); int ans=query(T[l],T[r+1],k); printf("%d\n",t[ans]); } } return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。