主席树

poj主席树裸题

http://poj.org/problem?id=2104

mark一下主席树的写法以及离散化的方法

#include<iostream>
#include<algorithm>
#define M 200005
using namespace std;
int tot=0;

struct Tree
{
    struct node
    {
        int l,r,v;
    } T[M<<4];
    void init(int &p,int l,int r)
    {
        p=++tot;
        T[p].v=0;
        if(l==r)return;
        int mid=l+r>>1;
        init(T[p].l,l,mid);
        init(T[p].r,mid+1,r);
    }
    void insert(int &p,int l,int r,int x,int pre)
    {
        p=++tot;
        T[p]=T[pre];
        T[p].v++;
        if(l==r)return;
        int mid=l+r>>1;
        if(x<=mid)insert(T[p].l,l,mid,x,T[pre].l);
        else insert(T[p].r,mid+1,r,x,T[pre].r);
    }
    int query(int id1,int id2,int l,int r,int k)
    {
        if(l==r)return l;
        int v1=T[T[id1].l].v;
        int v2=T[T[id2].l].v;
        int v=v2-v1,mid=l+r>>1;
        if(k<=v)return query(T[id1].l,T[id2].l,l,mid,k);
        return query(T[id1].r,T[id2].r,mid+1,r,k-v);
    }
} CT;


int root[M],rt;
int team1[M],team2[M],team3[M];
int main()
{
    int n,m,a,b,c;
    scanf("%d %d",&n,&m);
    for(int i=1; i<=n; i++)scanf("%d",&team1[i]),team2[i]=team1[i];

    sort(team2+1,team2+1+n);
    int size=unique(team2+1,team2+1+n)-team2-1;

    CT.init(rt,1,size);
    root[0]=rt;

    for(int i=1; i<=n; i++)
    {
        int now=lower_bound(team2+1,team2+1+n,team1[i])-team2;

        CT.insert(root[i],1,size,now,root[i-1]);
        team3[now]=team1[i];
    }

    for(int i=1; i<=m; i++)
    {
        scanf("%d %d %d",&a,&b,&c);
        printf("%d
",team3[CT.query(root[a-1],root[b],1,size,c)]);
    }
    return 0;
}
View Code
路漫漫其修远兮,吾将上下而求索
原文地址:https://www.cnblogs.com/tian-luo/p/9108208.html