初学主席树

原创 2016年08月29日 12:56:11

关于知识点的请看链接(我翻了n个blog,就这个写的最明白):点击打开链接

代码:(区间第k大)

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#define lson l, m
#define rson m+1, r
using namespace std;
const int N=1e5+5;
int L[N<<5], R[N<<5], sum[N<<5];
int tot;
int a[N], T[N], Hash[N];
int build(int l,int r)
{
       int rt=(++tot);
       sum[rt]=0;
       if(l<r)
       {

           int m=(r+l)>>1;
           L[rt]=build(lson);
           R[rt]=build(rson);
       }
    return rt;
}
int update(int pre,int l,int r,int x)
{
    int rt=(++tot);
    L[rt]=L[pre],R[rt]=R[pre],sum[rt]=sum[pre]+1;
    if(l<r)
    {
        int m=(r+l)>>1;
        if(x<=m)
        {
            L[rt]=update(L[pre],lson,x);
        }
        else
            R[rt]=update(R[pre],rson,x);
    }
    return rt;
}
int query(int u,int v,int l,int r,int k)
{
    if(l>=r)
        return l;
    int m=(l+r)>>1;
    int num=sum[L[v]]-sum[L[u]];
    if(num>=k)
    {
        return query(L[u],L[v],lson,k);
    }
    else
        return query(R[u],R[v],rson,k-num);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        tot=0;
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            Hash[i]=a[i];
        }
        sort(Hash+1,Hash+1+n);
        int d=unique(Hash+1,Hash+1+n)-Hash-1;
        T[0]=build(1,d);
        for(int i=1;i<=n;i++)
        {
            int x=lower_bound(Hash+1,Hash+d+1,a[i])-Hash;
            T[i]=update(T[i-1],1,d,x);
        }
        while(m--)
        {
            int l,r,k;
            scanf("%d%d%d",&l,&r,&k);
            int x=query(T[l-1],T[r],1,d,k);
            printf("%d\n",Hash[x]);
        }
    }
}

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<math.h>
#include<string.h>
#define ll long long
using namespace std;
const int N=1e6+6;
vector<int>p;
int cnt,n,m,x,y,k,root[N],a[N];
struct node{int l,r,sum;}T[N*40];
int getid(int x){ return lower_bound(p.begin(),p.end(),x)-p.begin()+1;}
void update(int l,int r,int &x,int y,int pos)
{
    T[++cnt]=T[y],T[cnt].sum++,x=cnt;
    if(l==r) return ;
    int mid=(r+l)>>1;
    if(mid>=pos)
        update(l,mid,T[x].l,T[y].l,pos);
    else
        update(mid+1,r,T[x].r,T[y].r,pos);
}
int query(int l,int r,int x,int y,int k)
{
    if(l==r) return l;
    int mid=(r+l)>>1;
    int sum=T[T[y].l].sum-T[T[x].l].sum;
    if(sum>=k)
        return query(l,mid,T[x].l,T[y].l,k);
    else
        return query(mid+1,r,T[x].r,T[y].r,k-sum);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),p.push_back(a[i]);
    sort(p.begin(),p.end()),p.erase(unique(p.begin(),p.end()),p.end());
    for(int i=1;i<=n;i++) update(1,n,root[i],root[i-1],getid(a[i]));
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&k);
        printf("%d\n",p[query(1,n,root[x-1],root[y],k)-1]);
    }
    return 0;
}


版权声明:加油 加油 加油^-^

主席树 初学

现在才开始学主席树(←弱(。・・)ノ)。不过不带修改的话代码还是很简单的嘛。。。或者说应该叫可持久化线段树?     首先对数的区间进行离散化,这样下面的a[i]都默认为离散化以后的结果了。     ...
  • lych_cys
  • lych_cys
  • 2016年02月11日 17:33
  • 761

主席树小结

简直卧槽了,充满RE的一天,没有太完成目标,算上昨天刷的一道主席树一共五道,算是入门了吧。 主席树可以认为是一种前缀和,表示的是每一个数出现的次数(当然必须要离散化),一种类似线段树的建法,为了节省...
  • u012288458
  • u012288458
  • 2015年08月05日 23:43
  • 2399

数据结构----主席树

这两天一直在看各种树~划分树,左偏树,主席树,伸展树~~~好乱~~ 一听到主席树这个名字的时候感觉好奇怪,为什么会叫主席树,感觉好难好高大上,所以一直敬而远之,,,,,主席树是一个大牛的拼音缩写H...
  • Lin_disguiser
  • Lin_disguiser
  • 2016年08月02日 13:36
  • 1419

带修改的主席树

时间空间复杂度均为n*log^2,时间还好,空间简直爆炸。。。 #include #include #include #include #include #include #in...
  • u014258433
  • u014258433
  • 2016年10月05日 18:16
  • 500

最详细的讲解,让你一次学会主席树

好久以前就想学习主席树这个黑科技,一直觉得很难,然后平时上课也没有什么好的时间,所以一直搁置到现在,最近遇到了一个比较简单,比较经典的问题,求区间第k小,比如poj2104,没有更新操作,只有查询操作...
  • creatorx
  • creatorx
  • 2017年07月19日 19:41
  • 1454

bzoj2588Spoj 10628. Count on a tree 树上主席树

比较经典的树上主席树,然而改了半天,tmd发现线段树开大了导致TLE?????这TM都能T?醉了,虽然我知道开大空间可能会T,但没想到有一天自己亲身成为实验体QAQ。。跟普通的主席树其实没什么区别,就...
  • qq_35866453
  • qq_35866453
  • 2017年06月08日 21:26
  • 206

主席树初学总结

转自:点击打开链接 主席树又称函数式线段树,顾名思义,也就是通过函数来实现的线段树,至于为什么叫主席树,那是因为是fotile主席创建出来的这个数据结构(其实貌似是当初主席不会划分树而自...
  • qq_34374664
  • qq_34374664
  • 2017年09月08日 14:27
  • 249

可修改主席树

前面讲完了主席树,那现在就来考虑可修改的主席树。 如果直接修改主席树,我们就需要用O(nlog2n)O_{(n log_2n)}的时间来逐个逐个修改,那么我们可否用更小的时间来修改呢? 我们之所以...
  • samjia2000
  • samjia2000
  • 2015年08月13日 21:35
  • 2278

【BZOJ2809】【codevs1763】派遣,主席树记录前缀和

你的笑容就像蝴蝶拍翅,如果可以,我想永远收藏。
  • xym_CSDN
  • xym_CSDN
  • 2016年05月06日 07:35
  • 294

主主主主主席树Orz

断断续续一个月,才稍稍搞明白一点主席树,真是累煞我也。果然遇上这种高级...
  • wjfwzzc
  • wjfwzzc
  • 2014年04月27日 01:17
  • 2355
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:初学主席树
举报原因:
原因补充:

(最多只允许输入30个字)