先说下权值线段树的概念吧

权值平均树 就是指区间维护值为这个区间内点出现次数和的线段树

用这个加权线段树 解决第k大问题就很方便了

int query(int l,int r,int rt,int k)//找第k大的数
{
if
(l==r) return l;
int
m=(l+r)/2;
if
(k<=sum[rt<<1]) return query(lson,k);//看左儿子的sum是否大于k大于的话 说明第k大的树在左儿子(利用出现的次数进行比对---建树的时候 边界是递增的)
else return
query(rson,k-sum[rt<<1]);
}
最后说一下使用权值线段树容易出现的问题 在建树的过程中 树的最大边界得包括我们需要的数据 那么问题来了 当数据很大的时候 不久爆内存了
这里得将数据离散化一下
什么是离散化呢 就是将数据映射成紧凑的数据 三个步骤
1.排序 2.去重 unqinue()函数。。 3.二分定位 用位置映射数据(lower_bound函数。。)

附上吴迎学长离散化的标准代码

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int a[100],b[100],c[100],n;
int solve()//离散化
{
for(int i=0;i<n;i++) b[i]=a[i];
sort(b,b+n);
int m=unique(b,b+n)-b;//去重
for(int i=0;i<n;i++) c[i]=lower_bound(b,b+m,a[i])-b;//二分找对应位置
for(int i=0;i<n;i++) printf("%d ",c[i]);
}
int main()
{ freopen("in.txt","r",stdin);
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
solve();
return 0;
}

再说说5249吧。,。 看了下吴迎学长的代码。。 感触挺深。 自己按照思路码了一遍 库函数好用

#include<cstdio>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#define lson l,m,rt<<1 //显得代码比较精简
#define rson m+1,r,rt<<1|1
#define maxn 10005
using namespace std;
int
sum[maxn<<];
int
n,a[maxn],b[maxn],c[maxn];
void
Pushup(int rt)
{

sum[rt]=sum[rt<<]+sum[rt<<|];
}

void
build(int l,int r,int rt)
{

if
(l==r)
{

sum[rt]=;
return
;
}

int
m=(l+r)/;
build(lson);
build(rson);
Pushup(rt);
}

void
updata(int l,int r,int rt,int temp,int flag)
{

if
(l==r)
{

sum[rt]+=flag;
return
;
}

int
m=(l+r)/;
if
(temp<=m) updata(lson,temp,flag);//
else updata(rson,temp,flag);
Pushup(rt);
}

int
query(int l,int r,int rt,int k)//找第k大的数
{
if
(l==r) return l;
int
m=(l+r)/;
if
(k<=sum[rt<<]) return query(lson,k);
else return
query(rson,k-sum[rt<<]);
}

int
main()
{

int
t=;
while
(~scanf("%d",&n))//由于需要离散化的过程 我们需要离线写
{
char
op[];
queue<int> que;
// freopen("in.txt","r",stdin);
for(int i=;i<=n;i++)
{

scanf("%s",op);
if
(op[]=='i') scanf("%d",&a[i]);
else if
(op[]=='o') a[i]=-;
else
a[i]=-;
}

int
m=;
for
(int i=;i<=n;i++)
{

if
(a[i]>=) b[m]=a[i],c[m++]=a[i];
}

sort(c+,c+m);
int
mm=unique(c+,c+m)-(c+);//离散的排序 去重 unique函数的参数为需要去重的范围 返回值为最后一个去重过程的函数 还有就是这个函数只对相邻的数去重
build(,mm,);
printf("Case #%d:\n",++t);
// cout<<mm<<endl;
// for(int i=1;i<=mm;i++) cout<<c[i]<<endl;
for(int i=;i<=n;i++)
{

if
(a[i]>=)
{

int
temp=lower_bound(c+,c+mm+,a[i])-c;//离散坐标对应
updata(,mm,,temp,);
// cout<<temp<<endl;
// for(int i=1;i<=7;i++) cout<<"in"<<sum[i]<<endl;
que.push(a[i]);
}

else if
(a[i]==-)
{

int
ret=que.front();
int
temp=lower_bound(c+,c+mm+,ret)-c;// 在c数组中找到第一个不小于ret的数
updata(,mm,,temp,-);
//for(int i=1;i<=7;i++) cout<<' '<<"out"<<sum[i]<<endl;
que.pop();
}

else

{

// cout<<que.size()/2+1<<endl;
printf("%d\n",c[query(,mm,,(que.size()/+))]);
}
}
}

return
;
}

区间第k大问题 权值线段树 hdu 5249的更多相关文章

  1. HDU 6464 权值线段树 && HDU 6468 思维题

    免费送气球 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  2. BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)

    题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...

  3. 动态求区间K大值(权值线段树)

    我们知道我们可以通过主席树来维护静态区间第K大值.我们又知道主席树满足可加性,所以我们可以用树状数组来维护主席树,树状数组的每一个节点都可以开一颗主席树,然后一起做. 我们注意到树状数组的每一棵树都和 ...

  4. 【bzoj3110】[Zjoi2013]K大数查询 权值线段树套区间线段树

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...

  5. 【bzoj3065】带插入区间K小值 替罪羊树套权值线段树

    题目描述 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间k小值.他每次向它的随从伏特提出 ...

  6. 【BZOJ3065】带插入区间K小值 替罪羊树+权值线段树

    [BZOJ3065]带插入区间K小值 Description 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理 ...

  7. 3065: 带插入区间K小值_树套树_替罪羊树_权值线段树

    经过周六一天,周一3个小时的晚自习,周二2个小时的疯狂debug,终于凭借自己切掉了这道树套树题. Code: #include <cstdio> #include <algorit ...

  8. BZOJ3110[Zjoi2013]K大数查询——权值线段树套线段树

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是 ...

  9. HDU6621 K-th Closest Distance 第 k 小绝对值(主席树(统计范围的数有多少个)+ 二分 || 权值线段树+二分)

    题意:给一个数组,每次给 l ,r, p, k,问区间 [l, r] 的数与 p 作差的绝对值的第 k 小,这个绝对值是多少 分析:首先我们先分析单次查询怎么做: 题目给出的数据与多次查询已经在提示着 ...

随机推荐

  1. Python 自学笔记(七)

    1.定义函数和调用函数 1-1.定义函数 定义函数的语法书写:def 函数名(参数名)(注:括号内可以为空,也可以为多个参数,多个参数间用逗号隔开即可) 由上可以看出,函数默认返回None 2.函数的 ...

  2. Qt编写自定义控件47-面板区域控件

    一.前言 在很多web网页上,经常可以看到一个设备对应一个面板,或者某种同等类型的信息全部放在一个面板上,该面板还可以拖来拖去的,这个控件首次用在智能访客管理平台中,比如身份证信息一个面板,访客信息一 ...

  3. VBA基础出发

    一.什么是VBA,学习的原因是什么. Visual Basic for Applicaion(VBA)是Visual Basic的一种宏语言,主要用来扩展Windows的应用程序功能.在日常生活中,使 ...

  4. Eclipse整合SSM框架+AOP+全局异常处理

    永久有效 链接: https://pan.baidu.com/s/1FlSP3a4Px05j3bB_miCOPQ 提取码: aa8w

  5. Docker 部署 ELK 收集 Nginx 日志

    一.简介 1.核心组成 ELK由Elasticsearch.Logstash和Kibana三部分组件组成: Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引 ...

  6. iOS 点击空白处收回键盘的几个简单代码

    //收回键盘1 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self.view.subviews enumer ...

  7. 123457---小小数学家--com.twoapp.xiaoxiaoshuxuejia

    小小数学家--com.twoapp.xiaoxiaoshuxuejia

  8. robot:生成随机的8为纯数字

    1.引进random库 2.注意最后面的random为需要引入的包

  9. eclipse设置html js css自动提示

    eclipse也可以像Visual Studio 2008那样完全智能提示HTML/JS/CSS代码,使用eclipse自带的插件,无需另外安装插件,具体步骤如下 1.打开eclipse→Window ...

  10. vim文本编辑器的介绍及使用

    (一)什么是vim编辑器 在Linux系统中配置应用服务,实际上就是在修改它的配置文件(配置文件可能有多个,其中包含不同的参数),而且日常工作中也一定免不了编写文档的事情吧,这些都是要通过文本编辑器来 ...