【poj2104-求区间第k大数(不修改)】主席树/可持续化线段树
第一道主席树~然而是道比较水的。。。因为它不用修改。。。
转载一个让我看懂的主席树的讲解吧:http://blog.csdn.net/regina8023/article/details/41910615 (未授权,侵权删)
---------------------------------------------------------------------------------------------------------------------
那么如果要询问i-j之间数字出现的次数怎么办呢?
因为每一棵线段树的区间都是相同的,所以要求l-r之间的数字的出现次数只要用前r位出现的次数减去前l-1位出现的次数,就是ans
但是如果有修改操作怎么办?
如果沿用上面的做法,那么修改操作是O(nlogn)的,查询是O(1)的,修改要花好长时间。。。
前缀和联想到了树状数组,那么将前缀和用树状数组维护的话修改是O(logn*logn),查询时O(logn),查询的时间虽然变长,但是修改的时间缩短许多!!
注意:
函数式线段树的数组要开大一点!!
---------------------------------------------------------------------------------------------------------------------
这题就是模版题啦,先离散,求区间第k大的时候lx=root[l-1],rx=root[r],两边同时走不断作差,看看左孩子的数量,如果k更大就减掉左孩子的到有右孩子中找。
代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std; const int N=,INF=(int)1e9+;
struct trnode{
int lc,rc,cnt;
}t[*N];
struct node{
int d,id;
}p[N];
int n,m,tl,mx;
int a[N],num[N],root[N]; bool cmp(node x,node y){return x.d<y.d;} int bt(int l,int r)
{
int x=++tl;
// a[x].l=l;a[x].r=r;
t[x].lc=t[x].rc=;
t[x].cnt=;
if(l<r)
{
int mid=(l+r)/;
t[x].lc=bt(l,mid);
t[x].rc=bt(mid+,r);
}
return x;
} int add(int rt,int x)
{
int now=++tl,tmp=now;
t[now].cnt=t[rt].cnt+;
int l=,r=mx,mid;
while(l<r)
{
mid=(l+r)/;
if(x<=mid)
{
t[now].lc=++tl;
t[now].rc=t[rt].rc;
rt=t[rt].lc;
now=tl;
r=mid;
}
else
{
t[now].lc=t[rt].lc;
t[now].rc=++tl;
rt=t[rt].rc;
now=tl;
l=mid+;
}
t[now].cnt=t[rt].cnt+;
}
return tmp;
} int query(int lx,int rx,int k)
{
int l=,r=mx,mid;
while(l<r)
{
mid=(l+r)/;
if(t[t[rx].lc].cnt-t[t[lx].lc].cnt>=k)
{
r=mid;
lx=t[lx].lc;
rx=t[rx].lc;
}
else
{
l=mid+;
k-=t[t[rx].lc].cnt-t[t[lx].lc].cnt;
lx=t[lx].rc;
rx=t[rx].rc;
}
}
return l;
} void output(int x)
{
printf("x = %d lc = %d rc = %d cnt = %d\n",x,t[x].lc,t[x].rc,t[x].cnt);
if(t[x].lc) output(t[x].lc);
if(t[x].rc) output(t[x].rc);
} int main()
{
freopen("a.in","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
tl=;mx=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
p[i].d=a[i];p[i].id=i;
}
sort(p+,p++n,cmp);
p[].d=INF;
for(int i=;i<=n;i++)
{
if(p[i].d!=p[i-].d) mx++,num[mx]=p[i].d;
a[p[i].id]=mx;
}
root[]=bt(,mx);
for(int i=;i<=n;i++)
root[i]=add(root[i-],a[i]);
// output(root[5]);
for(int i=;i<=m;i++)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",num[query(root[l-],root[r],k)]);
}
}
return ;
}
【poj2104-求区间第k大数(不修改)】主席树/可持续化线段树的更多相关文章
- [csu/coj 1080]划分树求区间前k大数和
题意:从某个区间内最多选择k个数,使得和最大 思路:首先题目给定的数有负数,如果区间前k大出现负数,那么负数不选和更大,于是对于所有最优选择,负数不会出现,所以用0取代负数,问题便转化为区间的前k大数 ...
- 线段树专题2-(加强版线段树-可持续化线段树)主席树 orz! ------用于解决区间第k大的问题----xdoj-1216
poj-2104(区间第K大问题) #include <iostream> #include <algorithm> #include <cstdio> #incl ...
- 区间前k小的和(权值线段树+离散化)--2019牛客多校第7场C--砍树
题目链接:https://ac.nowcoder.com/acm/contest/887/C?&headNav=acm 题意: 给你 n 种树,有 高度,花费和数量 ,现在问你最少需要花多少钱 ...
- 主席树的各类模板(区间第k大数【动,静】,区间不同数的个数,区间<=k的个数)
取板粗 好东西来的 1.(HDOJ2665)http://acm.hdu.edu.cn/showproblem.php?pid=2665 (POJ2104)http://poj.org/probl ...
- POJ2761---Feed the dogs (Treap求区间第k大)
题意 就是求区间第k大,区间 不互相包含. 尝试用treap解决一下 第k大的问题. #include <set> #include <map> #include <cm ...
- HDU-1754-I Hate It-线段树-求区间最值和单点修改
开学新拉的题目,老题重做,思路会稍微比之前清晰,不过这也算是一点点进步了. 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现 ...
- [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)
[BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...
- BZOJ3110[Zjoi2013]K大数查询——权值线段树套线段树
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是 ...
- bzoj 3110 [Zjoi2013]K大数查询——线段树套线段树(标记永久化)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3110 第一道线段树套线段树! 第一道标记永久化! 为什么为什么写了两个半小时啊…… 本想线段 ...
随机推荐
- 团队第一次作业 ——404 Note Found 团队
如果记忆是一个罐头的话,我希望这一罐罐头不会过期----<重庆森林> 404 Note Found Team 如果记忆是一个备忘录的话,别说了,它不会过期----<404 Note ...
- LintCode-70.二叉树的层次遍历 II
二叉树的层次遍历 II 给出一棵二叉树,返回其节点值从底向上的层次序遍历(按从叶节点所在层到根节点所在的层遍历,然后逐层从左往右遍历) 样例 给出一棵二叉树 {3,9,20,#,#,15,7}, 按照 ...
- CentOS 6安装thrift支持erlang开发
早前,在我的博文thrift多平台安装介绍了如何在debian/ubuntu下面安装thrift,并支持erlang开发的.而在CentOS平台下,并没有成功安装.经过不断摸索,终于成功了,这篇博文就 ...
- 什么是Oracle的分区表 (转 作者 陈字文)
假设我们现在正在酝酿经营一家图书馆,最初,我们只有十本书提供给大家来阅读和购买.对于十本书而言,我们可能只需要一个书架格子将其作为保存这十本书的容器就足够了,因为任何一个人都可以很轻松的扫一眼就可以将 ...
- 【Python】Python 新式类介绍
本文转载自:kaka_ace's blog 我们使用 Python 开发时, 会遇到 class A 和 class A(object) 的写法, 这在 Python2 里是有概念上和功能上的区别, ...
- BZOJ 1818 内部白点(离散化+树状数组)
此题就是1227 的弱化版. 画个图或者稍微证明一下就能够知道,一定不会超过一次变换. 那么我们只需要统计有多少个白点会变黑,换句话说就是有多少个白点上下左右都有黑点. 离散化横坐标,因为没有黑点在的 ...
- [洛谷P5068][Ynoi2015]我回来了
题目大意:给你一张$n(n\leqslant10^3)$个点$m(m\leqslant10^5)$个点的无向无权图,多组询问,每次询问给你一些二元组$(x_i,y_i)$,求有多少个$u$于至少一个二 ...
- Spring多个数据源问题:DataSourceAutoConfiguration required a single bean, but * were found
原因: @EnableAutoConfiguration 这个注解会把配置文件号中的数据源全部都自动注入,不会默认注入一个,当使用其他数据源时再调用另外的数据源. 解决方法: 1.注释掉这个注解 2. ...
- 【状压DP】【P3959】【NOIP2017D2T2】宝藏
Description 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 $n$ 个深埋在地下的宝藏屋, 也给出了这 $n$ 个宝藏屋之间可供开发的$ m$ 条道路和它们的长度. 小明决心亲自前往挖 ...
- Ext之延时加载
大家在多线程下使用extjs时应该遇到过以下情况: 同时渲染几个组件时,如果组件的内容是动态读取的时候,有时会出现后组件内容不是正确的渲染顺序出现的内容.比如同时渲染两个form,form的字段是动态 ...