Poj 2104(主席树入门

本文介绍使用主席树解决静态查询区间第k大问题的方法,通过具体代码实现和解析,为初学者提供了一个清晰易懂的入门指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:静态查询区间第k大.

主席树入门题目,之前看的很多资料一上来就是动态区间第k大,看得很费劲,后来找了个写得清晰的,感觉静态的还不算难,代码也不长.

/*
* @author:  Cwind
*/
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <set>
#include <cmath>
using namespace std;
#define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
#define pb push_back
#define PB pop_back
#define bk back()
#define fs first
#define se second
#define sq(x) (x)*(x)
#define eps (1e-6)
#define IINF (1<<29)
#define LINF (1ll<<59)
#define INF (1000000000)
#define FINF (1e3)
#define clr(x) memset((x),0,sizeof (x));
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> P;

const int maxn=3e6;
const int maxlen=1e5+300;
struct Node{
    int ls,rs,v;
    Node():ls(0),rs(0),v(0){}
}T[maxn];
int sz=0;
int d[maxlen],a[maxlen];
void insert(int &n,int l,int r,int x){
    T[++sz]=T[n];n=sz;
    T[n].v++;
    if(r-l<=1) return;
    int m=(r+l)>>1;
    if(x>=d[m]) insert(T[n].rs,m,r,x);
    else insert(T[n].ls,l,m,x);
}
int query(int i,int j,int l,int r,int k){
    if(r-l<=1) return d[l];
    int t=T[T[j].ls].v-T[T[i].ls].v;
    int m=(l+r)>>1;
    if(t>=k) return query(T[i].ls,T[j].ls,l,m,k);
    else return query(T[i].rs,T[j].rs,m,r,k-t);
}
int n,m;
int root[maxlen];
int main(){
    freopen("/home/files/CppFiles/in","r",stdin);
    cin>>n>>m;
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        d[i]=a[i];
    }
    sort(d,d+n);
    for(int i=0;i<n;i++){
        root[i+1]=root[i];
        insert(root[i+1],0,n,a[i]);
    }
       while(m--){
           int x,y,z;
           scanf("%d%d%d",&x,&y,&z);
           printf("%d\n",query(root[x-1],root[y],0,n,z));
       }
    return 0;
}
View Code

作为入门文章讲的很好:http://www.cnblogs.com/Rlemon/archive/2013/05/23/3094635.html

转载于:https://www.cnblogs.com/Cw-trip/p/4854972.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值