1. 程式人生 > >LGOJ P3834 【模板】可持久化線段樹 1(主席樹)

LGOJ P3834 【模板】可持久化線段樹 1(主席樹)

持久 else amp scan modify str 線段樹 unique return

代碼

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

struct node
{
    node *Lnode,*Rnode;
    int val;
    
    node()
    {
        Lnode=NULL;
        Rnode=NULL;
        val=0;
        
        return;
    }
    
    void clone(node* N)
    {
        Lnode=N->Lnode;
        Rnode=N->Rnode;
        val=N->val;
        
        return;
    }
}tree[3000005],*root[5005],*tail=tree;
int a[100005],b[100005];

node* build(int L,int R)
{
    node *O=(++tail);
    
    if(L==R) return O;
    
    int M=(L+R)>>1;
    
    O->Lnode=build(L,M);
    O->Rnode=build(M+1,R);
    
    return O;
}

node* modify(node* N,int L,int R,int pos)
{
    node *O=(++tail);
    
    O->clone(N);
    O->val++;
    
    if(L==R) return O;
    
    int M=(L+R)>>1;
    
    if(pos<=M) O->Lnode=modify(N->Lnode,L,M,pos);
    else O->Rnode=modify(N->Rnode,M+1,R,pos);
    
    return O;
}

int query(node* N,node* O,int L,int R,int pos)
{
    if(L==R) return L;
    
    int M=(L+R)>>1,npos=O->Lnode->val-N->Lnode->val;
    
    if(npos>=pos) return query(N->Lnode,O->Lnode,L,M,pos);
    return query(N->Rnode,O->Rnode,M+1,R,pos-npos);
}

int main()
{
    int n,m,cnt;
    
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        
        b[i]=a[i];
    }
    
    stable_sort(b+1,b+n+1);
    cnt=unique(b+1,b+n+1)-b-1;
    root[0]=build(1,cnt);
    for(int i=1;i<=n;i++)
    {
        int tmp=lower_bound(b+1,b+cnt+1,a[i])-b;
        
        root[i]=modify(root[i-1],1,cnt,tmp);
    }
    while(m--)
    {
        int i,j,k,p;
        
        scanf("%d%d%d",&i,&j,&k);
        
        p=query(root[i-1],root[j],1,cnt,k);
        
        printf("%d\n",b[p]);
    }
    
    return 0;
}

LGOJ P3834 【模板】可持久化線段樹 1(主席樹)