HDU - 2665 Kth number 主席树/可持久化权值线段树
题意
给一个数列,一些询问,问$[l,r]$中第$K$大的元素是哪一个
题解:
写法很多,主席树是最常用的一种之一
除此之外有:划分树,莫队分块,平衡树等
主席树的定义其实挺模糊,
一般认为就是可持久化线段树/函数式线段树的这种实现方式
被用来求区间第$K$大的时候,是可持久化的权值线段树
主席树的特点就是 $[l,r]$的区间信息可以通过创造的第$r$颗树的减去第$l-1$颗树得到
具体思路就是:
将数列的值进行排序,去重
对于原序列的每一个值,依次插入可持久化的权值线段树,将它所在排序位置权值+1
在线段树中,每一次插入实际上都会开一颗节点为$log(n)$新的线段树,树根保存为$rt_i$,存有$[1,i]$的区间信息
然后对于每次询问$[l,r]$,$tree_r - tree_{l-1}$的第$K$个数字即为答案
*树之间的减法是指,对于每个节点的权值进行相减
显然$tree_{i+m}-tree_i$最终得到的树与权值,就代表了$[i+1,i+m]$之间插入的元素,也就是区间$[i+1,m]$的权值树,就可以当做数列整体第$K$大解决了
#include <bits/stdc++.h>
#define nd seg[now]
#define ndp seg[pre]
#define mid ((s+t)>>1)
using namespace std;
const int maxn=1e5+10;
vector<int>pos;
int casn,n,m,k;
int num[maxn],rt[maxn],size;
struct node{
int l,r,sum;
}seg[maxn*20];
void maketree(int s=1,int t=n,int &now=rt[0]){
now=++size;nd={s,t,0};
if(s==t) return ;
maketree(s,mid,nd.l);maketree(mid+1,t,nd.r);
}
void update(int &now,int pre,int k,int s=1,int t=n){
now=++size;nd=ndp,nd.sum++;
if(s==t) return ;
if(k<=mid)update(nd.l,ndp.l,k,s,mid);
else update(nd.r,ndp.r,k,mid+1,t);
}
int query(int now,int pre,int k,int s=1,int t=n){
if(s==t) return s;
int sum=seg[ndp.l].sum-seg[nd.l].sum;
if(k<=sum) return query(nd.l,ndp.l,k,s,mid);
else return query(nd.r,ndp.r,k-sum,mid+1,t);
}
int main(){
scanf("%d",&casn);
while(casn--){
scanf("%d%d",&k,&m);
pos.clear();
size=0;
for(int i=1;i<=k;i++){
scanf("%d",num+i);
pos.push_back(num[i]);
}
sort(pos.begin(),pos.end());
pos.erase(unique(pos.begin(),pos.end()),pos.end());
n=pos.size();
maketree(1,n,rt[0]);
for(int i=1;i<=k;i++){
int id=lower_bound(pos.begin(),pos.end(),num[i])-pos.begin()+1;
update(rt[i],rt[i-1],id);
}
while(m--){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
printf("%d\n",pos[query(rt[a-1],rt[b],c)-1]);
}
}
return 0;
}

HDU - 2665 Kth number 主席树/可持久化权值线段树的更多相关文章
- 2019.01.21 bzoj2441: [中山市选2011]小W的问题(树状数组+权值线段树)
传送门 数据结构优化计数菜题. 题意简述:给nnn个点问有多少个www型. www型的定义: 由5个不同的点组成,满足x1<x2<x3<x4<x5,x3>x1>x2 ...
- HDU 6464.免费送气球-动态开点-权值线段树(序列中第first小至第second小的数值之和)(感觉就是只有一个状态的主席树) (“字节跳动-文远知行杯”广东工业大学第十四届程序设计竞赛)
免费送气球 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- hdu 2665 Kth number 主席树
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Prob ...
- 权值线段树&&可持久化线段树&&主席树
权值线段树 顾名思义,就是以权值为下标建立的线段树. 现在让我们来考虑考虑上面那句话的产生的三个小问题: 1. 如果说权值作为下标了,那这颗线段树里存什么呢? ----- 这颗线段树中, 记录每个值出 ...
- Dynamic Rankings(树状数组套权值线段树)
Dynamic Rankings(树状数组套权值线段树) 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[ ...
- BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)
题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...
- 【bzoj3110】[Zjoi2013]K大数查询 权值线段树套区间线段树
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...
- 对权值线段树剪枝的误解--以HDU6703为例
引子 对hdu6703,首先将问题转化为"询问一个排列中大于等于k的值里,下标超过r的最小权值是多少" 我们采用官方题解中的做法:权值线段树+剪枝 对(a[i],i)建线段树,查询 ...
- 主席树[可持久化线段树](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 ...
随机推荐
- [C#]一个简易的、轻量级的方法并行执行线程辅助类
一个简易的.轻量级的方法并行执行线程辅助类 在实际应用中,经常要让多个方法并行执行以节约运行时间,线程就是必不可少的了,而多线程的管理经常又是一件头疼的事情,比如方法并行执行异步的返回问题,方法并 ...
- vue实现简单的全选、反选、不选
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- [Android] Android利用Coordinatorlayout+AppbarLayout实现折叠式布局
折叠式布局在App中相当常见,给人一种科技感,充满良好的用户体验. 本文就以两个简单的例子,来举例说明基本折叠式布局: 首先需要在app/build.gradle下添加如下依赖: compile 'c ...
- git步骤
1.New一个Repositories 2.拿到这个仓库的URL 3.git clone https://github.com/zhuobo/new.git 4.进入到clone下来的文件夹,然后gi ...
- 解决浏览器跨域限制方案之CORS
一.什么是CORS CORS是解决浏览器跨域限制的W3C标准,详见:https://www.w3.org/TR/cors/. 根据CORS标准的定义,在浏览器中访问跨域资源时,需要做如下实现: 服务端 ...
- List<string>序列化与反序列化一个小坑
Newtonsoft序列化与反序列化有两个重载方法,带<T>和不带<T>的 如果将一个List<String>序列化为jsonStr后,再反序列化,会变成JArra ...
- 三十四、Linux 进程与信号——信号特点、信号集和信号屏蔽函数
34.1 信号特点 信号的发生是随机的,但信号在何种条件下发生是可预测的 进程杠开始启动时,所有信号的处理方式要么默认,要么忽略:忽略是 SIGUSR1 和 SIGUSR2 两个信号,其他都采取默认方 ...
- 三、文件IO——系统调用(续)
3.2.4 read 函数--- 读文件 read(由已打开的文件读取数据) #include<unistd.h> ssize_t read(int fd, void * buf, siz ...
- Burp Collaborator资源整合
1.http://www.ninoishere.com/burp-collaborator/ Burp Collaborator使用 2.https://www.anquanke.com/po ...
- intptr_t 指针
对于64为系统: typedef signed char int8_t; typedef short int int16_t; typedef int int32_t; # if __WORDSI ...