题意:给出1e5个数,向你提5000问,L到R间的第K个数是多少?

————————————————————————————————————————————————————————

这个题着实没有其它很好的办法,是主席树的经典题目。

主席树,又叫可持久化线段树或者函数式线段树。我只知道这些了,据说是一位大神没学会划分树就自己搞了这么个替代品,结果,比原来的还要强。哎~,真不知道这群大神的脑子是咋整的,膜拜吧!

本人水平有限,这是我见过的最神奇的数据结构了,感觉比伸展树、熟练剖分神奇多了,鼓捣了大半天才明白其中的原理。

说一下思路:

因为是求第k大的数,所以线段树是不行的,因为数是排好序的,所以伸展树好像也不好解决。

所以主席树用到了前缀和的思想,如果知道每个数在L前出现了几次,R前出现了几次,做差就可以在L~R间出现了几次,自然也就知道k大了!

所以,第一步把所有的数排序、去重。

数列:2 4 6 8 8 6 4 2

hash:2 4 6 8

数列变为:1 2 3 4 4 3 2 1(就是各个数在hash中的排序)

第二部建n+1个线段树,就是按照数列的顺序每读入一个数就建一个线段树,把新树在上一颗树的基础上把这个数字按照去重后的排序加入当前线段树。

这样求L~R的k值就用线段树R减去线段树L-1,在差中找k大值就可以了。

......

出现的问题:超空间

这个事大神替我们想到了,那就是每一个线段树与上一个线段树只有一条路径(根到叶)不同,所以,新树除了这条路径外所有节点都用上一个线段树的。

这样空间为第一颗线段树(4*n)+每个数字一条链(n*logn)

代码敲了1天多,主要是本人习惯于用指针和new,但是这次点太多,超时了。没办法只好给出数组模拟指针。ok!

网上有人说可以一次性malloc多个,这样可以省时通过,没来得及试,不过应该可以,但是就没有了指针+new的灵活性,不做也罢。

但是没舍得把指针的丢掉,这个理解起来清楚容易,哎~,就这麽着吧!

————————————————————————————————————————————————————————

数组版:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std;
const int maxn=;
const int maxnn=;
int root[maxn],ls[maxnn],rs[maxnn],cnt[maxnn],tot;
int sz[maxn],hash[maxn];
void build(int &cur,int l,int r)
{
cur=tot++;
cnt[cur]=;
if(l!=r)
{
int mid=(l+r)/;
build(ls[cur],l,mid);
build(rs[cur],mid+,r);
}
}
void update(int pre,int ps,int &cur,int l,int r)
{
cur=tot++;
cnt[cur]=cnt[pre]+;
ls[cur]=ls[pre];rs[cur]=rs[pre];
if(l==r)return ;
int mid=(l+r)/;
if(ps<=mid)update(ls[pre],ps,ls[cur],l,mid);
else update(rs[pre],ps,rs[cur],mid+,r);
}
int query(int lt,int rt,int l,int r,int k)
{
if(l==r)return l;
int mid=(l+r)/,cha=cnt[ls[rt]]-cnt[ls[lt]];
if(k<=cha)return query(ls[lt],ls[rt],l,mid,k);
else return query(rs[lt],rs[rt],mid+,r,k-cha);
}
int main()
{
int m,n,l,r,k;
while(scanf("%d%d",&n,&m)==)
{
for(int i=;i<=n;++i)
{
scanf("%d",sz+i);
hash[i]=sz[i];
}
sort(hash+,hash+n+);
int siz=unique(hash+,hash++n)-hash-;
for(int i=;i<=n;++i)
sz[i]=lower_bound(hash+,hash++siz,sz[i])-hash;
tot=;
build(root[],,siz);
for(int i=;i<=n;++i)
update(root[i-],sz[i],root[i],,siz);
while(m--)
{
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",hash[query(root[l-],root[r],,siz,k)]);
}
}
return ;
}

指针版(由于多次malloc,超时了)

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
struct node
{
int cnt;
node *ch[];
int l,r;
}* root[maxn];
int n,mm,l,r,k;
int sz[maxn],hash[maxn]; void readint(int &x)
{
char c=getchar();
int f=;
for(;c<''||c>'';c=getchar())if(c=='-')f=-f;
x=;
for(;c<=''&&c>='';c=getchar())x=x*+c-'';
x=x*f;
}
void build(node * &cur,int l,int r)
{
cur=(node *)malloc(sizeof(node));
cur->cnt=;
cur->ch[]=cur->ch[]=NULL;
cur->l=l;cur->r=r;
if(l!=r)
{
int mid=(l+r)/;
build(cur->ch[],l,mid);
build(cur->ch[],mid+,r);
}
}
void update(node * pre,int ps,node * &cur,int l,int r)
{
cur=(node *)malloc(sizeof(node));
cur->cnt=pre->cnt+;
cur->l=pre->l;cur->r=pre->r;
cur->ch[]=pre->ch[];
cur->ch[]=pre->ch[];
if(l==r)return ;
int mid=(l+r)/;
if(ps<=mid)update(pre->ch[],ps,cur->ch[],l,mid);
else update(pre->ch[],ps,cur->ch[],mid+,r);
}
int query(node * lt,node *rt,int l,int r,int k)
{
if(l==r)return l;
int mid=(l+r)/,cha=rt->ch[]->cnt - lt->ch[]->cnt;
if(k<=cha)return query(lt->ch[],rt->ch[],l,mid,k);
else return query(lt->ch[],rt->ch[],mid+,r,k-cha);
}
int main()
{
while(scanf("%d%d",&n,&mm)==)
{
for(int i=;i<=n;++i)
{
readint(sz[i]);
hash[i]=sz[i];
}
sort(hash+,hash+n+);
int siz=unique(hash+,hash+n+)-hash-;
for(int i=;i<=n;++i)
sz[i]=lower_bound(hash+,hash+siz+,sz[i])-hash;
build(root[],,siz);
for(int i=;i<=n;++i)
update(root[i-],sz[i],root[i],,siz);
while(mm--)
{
readint(l);readint(r);readint(k);
printf("%d\n",hash[query(root[l-],root[r],,siz,k)]);
}
}
return ;
}

POJ2104 K-TH NUMBER 传说中的主席树的更多相关文章

  1. [POJ2104] K – th Number (可持久化线段树 主席树)

    题目背景 这是个非常经典的主席树入门题--静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输 ...

  2. K-th Number Poj - 2104 主席树

    K-th Number Poj - 2104 主席树 题意 给你n数字,然后有m次询问,询问一段区间内的第k小的数. 解题思路 这个题是限时训练做的题,我不会,看到这个题我开始是拒绝的,虽然题意清晰简 ...

  3. BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数

    BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数 Description  dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯 竭 ...

  4. 主席树总结(经典区间第k小问题)(主席树,线段树)

    接着上一篇总结--可持久化线段树来整理吧.点击进入 这两种数据结构确实有异曲同工之妙.结构是很相似的,但维护的主要内容并不相同,主席树的离散化.前缀和等思想也要更难理解一些. 闲话 话说刚学习主席树的 ...

  5. bzoj : 4504: K个串 区间修改主席树

    4504: K个串 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 268  Solved: 110[Submit][Status][Discuss] ...

  6. [poj2104] K-th Number (主席树)

    主席树 Description You are working for Macrohard company in data structures department. After failing y ...

  7. 可持久化线段树(主席树)(图文并茂详解)【poj2104】【区间第k大】

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=63740442 向大(hei)佬(e)实力学(di ...

  8. POJ 2104:K-th Number(主席树静态区间k大)

    题目大意:对于一个序列,每次询问区间[l,r]的第k大树. 分析: 主席树模板题 program kthtree; type point=record l,r,s:longint; end; var ...

  9. 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )

    在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...

随机推荐

  1. 使用 jQuery 和 CSS3 制作滑动导航菜单

    这个下拉菜单可以让你的网站非常优雅,滑动框导航效果令人印象深刻.此外,子菜单框也可以与此集成起来以使其更具吸引力.导航是网站成功的关键之一,有吸引力的导航能够引导用户浏览网站中的更多内容. 效果演示  ...

  2. Html + Css思维导图

    最近整理的一份Html和Css的思维导图,共享给初学者使用. 各个知识点的详细案例介绍,后期会分阶段依次发布,希望对大家学习html和css有帮助. 如果对文中的知识点有异议,欢迎随时拍砖! 后期也回 ...

  3. Egret白鹭H5小游戏开发入门(二)

    前言: 昨天的文章中简单的介绍了Egret白鹭引擎从安装到基本的使用配置等问题,今天着重介绍H5小游戏开发的起步阶段,如Wing面板的使用,素材的处理,类的说明,开始布局等等. 整体概况: 根据上一篇 ...

  4. SharePoint 2010 GridView/SPGridView完全应用系统样式

    自定义开发页面如果用到了GridView或SPGridView默认跟列表的样式是不一样的,如要要一样,需要: 1)aspx <asp:GridView DataKeyNames="ID ...

  5. JS判断用户手机是IOS还是Android

    $(function () { var u = navigator.userAgent, app = navigator.appVersion; var isAndroid = u.indexOf(' ...

  6. android FrameLayout详解

    首先看演示: FrameLayout框架布局是最简单的布局形式.所有添加到这个布局中的视图都以层叠的方式显示.第一个添加的控件被放在最底层,最后一个添加到框架布局中的视图显示在最顶层,上一层的控件会覆 ...

  7. 关于iOS的runtime

    runtime是一个很有意思的东西,如果你学iOS开发很经常就会用到或被问到runtime.那么runtime是什么呢,如何去了解它. runtime:中文名 运行时,系统在编译时留下的一些 类型,操 ...

  8. IOS开发基础知识--碎片32

    1:动画属性UIViewAnimationOptions说明 a:常规动画属性设置(可以同时选择多个进行设置) UIViewAnimationOptionLayoutSubviews:动画过程中保证子 ...

  9. UIButton

    //UIButton->UIControl->UIView //UIControl 带有操作的控件都是继承于它的 //UIButton  实例化  类方法实例化 //实例化时没有位置及大小 ...

  10. iOS 学习 - 16.绘制虚线

    //绘制虚线 -(void)set{ UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(, , , )]; [ ...