首页 > 其他分享 >可持久化线段树(主席树)

可持久化线段树(主席树)

时间:2024-08-18 21:06:46浏览次数:8  
标签:pr 持久 线段 tree 主席 query ll pl

区间第k大/小问题

洛谷P3834
好吧,区间问题,考虑线段树

でも,线段树能求解的问题须是大问题的解可以从小问题的解合并而来,显然,第k大/小问题不满足,不能直接用一颗树解决

考虑用多颗树
怎么想到的?我要是想到了我就成主席了
首先,烧烤一下如何用线段树求 1-i 的第 k 小值
烧烤ing……

以元素值为下标建树,线段树的点权表示这个区间有几个元素,查询,若当前节点的左儿子的点权 < k,则第 k 大的数在右儿子的区间里 ,> 则在左儿子里

就完了

更新ing

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=200005;
ll n,m,a[N],b[N],cnt;
ll root[N];
struct node{
	ll L,R,sum;
}tree[N<<5];
ll update(ll pre,ll pl,ll pr,ll x){
	ll rt=++cnt;
	tree[rt].L=tree[pre].L;
	tree[rt].R=tree[pre].R;
	tree[rt].sum=tree[pre].sum+1;
	ll mid=(pl+pr)>>1;
	if(pl<pr){
		if(x<=mid)
			tree[rt].L=update(tree[pre].L,pl,mid,x);
		if(x>mid)
			tree[rt].R=update(tree[pre].R,mid+1,pr,x);
	}
	return rt;
}
ll query(ll u,ll v,ll pl,ll pr,ll k){
	if(pl==pr)return pl;
	ll x=tree[tree[v].L].sum-tree[tree[u].L].sum;
	ll mid=(pl+pr)>>1;
	if(x>=k)return query(tree[u].L,tree[v].L,pl,mid,k);
	if(x<k)return query(tree[u].R,tree[v].R,mid+1,pr,k-x);
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		b[i]=a[i];
	}
	sort(b+1,b+1+n);
	ll size=unique(b+1,b+1+n)-b-1;
	for(int i=1;i<=n;i++){
		ll x=lower_bound(b+1,b+1+size,a[i])-b;
		root[i]=update(root[i-1],1,size,x);
	}
	for(int i=1;i<=m;i++){
		ll x,y,k;
		cin>>x>>y>>k;
		ll t=query(root[x-1],root[y],1,size,k);
		cout<<b[t]<<endl;
	}
	return 0;
}

标签:pr,持久,线段,tree,主席,query,ll,pl
From: https://www.cnblogs.com/Z-kazuha/p/18366086

相关文章

  • 刍议线段树 3 (扫描线)
    扫描线扫描线是一种另外的思想,只是其中会运用到线段树以求优化。所以不要将扫描线简单的并为线段树的一个小拓展。例题:https://www.luogu.com.cn/problem/P5490大意:求\(n\)个四边平行于坐标轴的矩形的面积并。思路:纵向分割图形我们考虑把这些纵向矩形分割。那么,总面积就......
  • 线段树模板,洛谷原题P3373
    线段树区间乘、加,范围求和,QWQ原题#include<bits/stdc++.h>#definePIIpair<int,int>#defineintlonglong#defineDBdoublenamespaceFastIO{ inlineintread(intMOD,int&ret){ charch=getchar();intngtv=1; if(MOD==0){while(ch<&#......
  • D46 2-SAT+线段树优化+二分 [ARC069F] Flags
    视频链接: [ARC069F]Flags-洛谷|计算机科学教育新生态(luogu.com.cn)//D462-SAT+线段树优化+二分O(nlognlogv)#include<iostream>#include<cstring>#include<algorithm>usingnamespacestd;#definemid((l+r)>>1)#definels(u<<1)#definer......
  • leetcode线段树(2940. 找到 Alice 和 Bob 可以相遇的建筑)
    前言经过前期的基础训练以及部分实战练习,粗略掌握了各种题型的解题思路。现阶段开始专项练习。描述给你一个下标从 0 开始的正整数数组 heights ,其中 heights[i] 表示第 i 栋建筑的高度。如果一个人在建筑 i ,且存在 i<j 的建筑 j 满足 heights[i]<heig......
  • 算法笔记——可持久化线段树
    维护历史值当要修改一个节点时,把跟他有关的线段树中所有节点舍弃,并建立新节点连接.代码如下:#include<bits/stdc++.h>usingnamespacestd;constintN=1e6+5;intn,m,a[N],root[N],top;structnode{ intl,r,val;}t[N*40];intclone(intx)//新建节点{ top++; t......
  • Redis持久化
    1、为啥需要持久化?因为Redis服务是使用内存存储的,一旦RedisServer停止工作或者服务重启等问题,RedisServer使用的内存将被清空,数据也就丢失了。所以持久化是保证数据备份的关键。2、Redis持久化有哪些方式?Redis提供了两种持久化方式——RDB(快照持久化方式)和AOF(日志......
  • 主席树做题记录
    主席树做题记录。主席树,即可持久化权值线段树。P3248[HNOI2016]树难爆了这题。题目中会多次把模板树的某个子树放到大树上的某个节点下,我们把这一整个子树看作一个大节点,把模板树、大树分别维护。具体的,模板树上需要倍增维护两点之间的距离,dfs序。大树上需要维护:大树上......
  • 有关线段树的一些细节理解
    写在前面本菜鸡线段树学了好多遍但是每次写还是得很长时间有时有一个细节还要琢磨半天所以为了今后避免以上事情发生本菜鸡决定将这么长时间以来对线段树的认识汇总好日后清算模板#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintN=1e5;i......
  • zkw线段树
    事情的起因是我某天吃晚饭时打算找个电子榨菜,然后b站搜索线段树,看到了一个名叫zkw线段树(即非递归线段树),由于不是面向Oier的,所以饭后我又找了几个博客看,现在写下心得记录(其实只是不想在书签留3个位置给线段树)为什么要学习非递归线段树,这个问题大部分博客解释为普通线段树......
  • 『线段树合并』Day7
    颓了一天了。md虽然还没有过线段树合并板题,但早就用过了。注意,单次合并复杂度是\(O(n\logn)\)的,但是一直合并,保证最终共有\(n\)个元素的话,总时间复杂度也是\(o(n\logn)\)的。不要理解成单次\(\logn\)。一个人千万不能忘记自己的初心,有时候需要静下心来想一想自己到底......