1. 程式人生 > >poj 2104主席樹求區間第k小

poj 2104主席樹求區間第k小

區間 ++ cto ast http lan air algorithm while

POJ - 2104

題意:求區間第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小