码迷,mamicode.com
首页 > 其他好文 > 详细

P3834 【模板】可持久化线段树 1(主席树)

时间:2018-08-11 01:23:06      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:pos   ==   putc   turn   get   using   algorithm   区间   ++   

板子。。。。

题意:给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值。

 

这个空间。。50倍。。。。

每次新开节点,与原来节点公用左右儿子(随便认儿子,然后在更新维护)

 

#include<cstdio>
#include<iostream>
#include<cctype>
#include<algorithm>
using namespace std;
#define nmr 205050
#define olinr return
#define love_nmr 0
int n;
int m;
int p;
int len;
int cnt;
int rt[nmr];
int ls[nmr<<5];
int rs[nmr<<5];
int num[nmr<<5];
int a[nmr];
int b[nmr];
inline int read()
{
    char ch=getchar();
    int f=1,x=0;
    while(!isdigit(ch))
    {
        if(ch==-)
            f=-f;
        ch=getchar();
    }    
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
inline void put(int x)
{
    if(x<0)
    {
        putchar(-);
        x=-x;
    }
    if(x>9)
        put(x/10);
    putchar(x%10+0);
}
inline void build(int &o,int l,int r)
{
    o=++cnt;
    if(l==r) olinr;
    int mid=(l+r)>>1;
    build(ls[o],l,mid);
    build(rs[o],mid+1,r);
}
inline int add(int o,int l,int r)
{
    int root=++cnt;
    ls[root]=ls[o];
    rs[root]=rs[o];
    num[root]=num[o]+1;
    if(l==r) olinr root;
    int mid=(l+r)>>1;
    if(p<=mid) ls[root]=add(ls[root],l,mid);
    if(p>mid) rs[root]=add(rs[root],mid+1,r);
    olinr root;
}
inline int query(int l,int r,int x,int y,int k)
{
    int ans=0;
    int pos=num[ls[y]]-num[ls[x]];
    if(l==r) olinr l;
    int mid=(l+r)>>1;
    if(k<=pos) ans=query(l,mid,ls[x],ls[y],k);
    if(k>pos) ans=query(mid+1,r,rs[x],rs[y],k-pos);
    return ans;
}
int main()
{
    n=read();
    m=read();
    for(int i=1;i<=n;i++)    
        b[i]=a[i]=read();
    sort(b+1,b+n+1);
    len=unique(b+1,b+n+1)-b-1;
    build(rt[0],1,len);
    for(int i=1;i<=n;i++)
    {
        p=lower_bound(b+1,b+len+1,a[i])-b;
        rt[i]=add(rt[i-1],1,len);
    }
    while(m--)
    {
        int l=read();
        int r=read();
        int k=read();
        put(b[query(1,len,rt[l-1],rt[r],k)]);
        putchar(\n);
    }
    olinr love_nmr;
}

 

P3834 【模板】可持久化线段树 1(主席树)

标签:pos   ==   putc   turn   get   using   algorithm   区间   ++   

原文地址:https://www.cnblogs.com/olinr/p/9457696.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!