poj 2104主席树求区间第k小
Posted %%%%%
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 2104主席树求区间第k小相关的知识,希望对你有一定的参考价值。
题意:求区间第k小
思路:无修改主席树
AC代码:
#include "iostream" #include "iomanip" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #pragma comment(linker, "/STACK:102400000,102400000") #define bug(x) cout<<x<<" "<<"UUUUU"<<endl; #define mem(a,x) memset(a,x,sizeof(a)) #define step(x) fixed<< setprecision(x)<< #define mp(x,y) make_pair(x,y) #define pb(x) push_back(x) #define ll long long #define endl ("\n") #define ft first #define sd second #define lrt (rt<<1) #define rrt (rt<<1|1) using namespace std; const ll mod=1e9+7; const ll INF = 1e18+1LL; const int inf = 1e9+1e8; const double PI=acos(-1.0); const int N=1e5+100; int ls[N*20],rs[N*20],rt[N],sum[N*20],cnt; int n,m,ran[N]; void creat(int &cur, int l, int r){ cur=++cnt; sum[cur]=0; if(l==r) return; int mid=l+r>>1; creat(ls[cur], l, mid); creat(rs[cur], mid+1, r); } void update(int &cur, int l, int r, int p, int last){ cur=++cnt; ls[cur]=ls[last]; rs[cur]=rs[last]; sum[cur] = sum[last]+1; if(l==r) return; int mid=l+r>>1; if(p<=mid) update(ls[cur], l, mid, p, ls[cur]); else update(rs[cur], mid+1, r, p, rs[cur]); } int query(int cur_l, int cur_r, int l, int r, int k){ if(l==r) return l; int t=sum[ls[cur_r]]-sum[ls[cur_l]]; int mid=l+r>>1; if(t>=k) return query(ls[cur_l], ls[cur_r], l, mid, k); else return query(rs[cur_l], rs[cur_r], mid+1, r, k-t); } struct Node{ int id, x; bool friend operator< (Node a, Node b){ return a.x<b.x; } bool friend operator== (Node a, Node b){ return a.x==b.x; } }a[N]; int main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); while(cin>>n>>m){ for(int i=1; i<=n; ++i){ cin>>a[i].x; a[i].id=i; } sort(a+1,a+1+n); cnt=0; int sz=n;//unique(a+1,a+1+n) - (a+1); ///cout<<sz<<endl; for(int i=1; i<=sz; ++i) ran[a[i].id]=i; creat(rt[0], 1, n); for(int i=1; i<=n; ++i){ //cout<<ran[i]<<endl; update(rt[i], 1, n, ran[i], rt[i-1]); } while(m--){ int l,r,k; cin>>l>>r>>k; cout<<a[query(rt[l-1], rt[r], 1, sz, k)].x<<endl; } } return 0; }
以上是关于poj 2104主席树求区间第k小的主要内容,如果未能解决你的问题,请参考以下文章
poj2104-求区间第k大数(不修改)主席树/可持续化线段树