poj 2104 K-th Number (静态区间第k大,主席树)

    xiaoxiao2025-11-10  6

    查询区间第K大,而且没有修改。

    使用划分树是可以做的。

    #include <set> #include <map> #include <stack> #include <queue> #include <deque> #include <cmath> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define L(i) i<<1 #define R(i) i<<1|1 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-9 #define maxn 100100 #define MOD 1000000007 const int MAXN = 100010; const int M = MAXN * 30; int n,q,m,tot; int a[MAXN], t[MAXN]; int T[M], lson[M], rson[M], c[M]; void Init_hash() { for(int i = 1; i <= n;i++) t[i] = a[i]; sort(t+1,t+1+n); m = unique(t+1,t+1+n)-t-1; } int build(int l,int r) { int root = tot++; c[root] = 0; if(l != r) { int mid = (l+r)>>1; lson[root] = build(l,mid); rson[root] = build(mid+1,r); } return root; } int hash(int x) { return lower_bound(t+1,t+1+m,x) - t; } int update(int root,int pos,int val) { int newroot = tot++, tmp = newroot; c[newroot] = c[root] + val; int l = 1, r = m; while(l < r) { int mid = (l+r)>>1; if(pos <= mid) { lson[newroot] = tot++; rson[newroot] = rson[root]; newroot = lson[newroot]; root = lson[root]; r = mid; } else { rson[newroot] = tot++; lson[newroot] = lson[root]; newroot = rson[newroot]; root = rson[root]; l = mid+1; } c[newroot] = c[root] + val; } return tmp; } int query(int left_root,int right_root,int k) { int l = 1, r = m; while( l < r) { int mid = (l+r)>>1; //printf("%d %d %d %d %d\n",l,r,left_root,right_root,k); if(c[lson[left_root]]-c[lson[right_root]] >= k ) { r = mid; left_root = lson[left_root]; right_root = lson[right_root]; } else { l = mid + 1; k -= c[lson[left_root]] - c[lson[right_root]]; left_root = rson[left_root]; right_root = rson[right_root]; } } return l; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(scanf("%d%d",&n,&q) == 2) { tot = 0; for(int i = 1;i <= n;i++) scanf("%d",&a[i]); Init_hash(); T[n+1] = build(1,m); for(int i = n; i ;i--) { int pos = hash(a[i]); T[i] = update(T[i+1],pos,1); } while(q--) { int l,r,k; scanf("%d%d%d",&l,&r,&k); printf("%d\n",t[query(T[l],T[r+1],k)]); } } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-1304051.html
    最新回复(0)