首页 > 其他分享 >【学习笔记】树套树

【学习笔记】树套树

时间:2023-09-03 17:57:38浏览次数:50  
标签:rr 树套 int cin 笔记 else 学习 rl rk

所谓树套树,其本质是通过用树维护一组树的根,从而维护强悍的数据

1 线段树套平衡树

线段树套

#include<bits/stdc++.h>
using namespace std;

#define MAXN 50005

int seg[MAXN<<2];
int amin=1000000,amax=0;

struct Node{
	int val,rnd,siz;
	int ch[2];	
}t[MAXN*80];
int tcnt=0;

int n,m;
int a[MAXN];
int rop,rl,rr,rk,rpos;
	
int nnode(int val){
	tcnt++;
	t[tcnt].ch[0]=0;
	t[tcnt].ch[1]=0;
	t[tcnt].val=val;
	t[tcnt].siz=1;
	t[tcnt].rnd=rand();

	return tcnt;
}
inline void upd(int id){
	t[id].siz=t[t[id].ch[0]].siz+t[t[id].ch[1]].siz+1;
} 
inline void split(int id,int val,int &x,int &y){
	if(!id){
		x=0;
		y=0;
		return;
	}
	if(t[id].val<=val){
		x=id;
		split(t[id].ch[1],val,t[id].ch[1],y);
		upd(id);
		return;
	}else{
		y=id;
		split(t[id].ch[0],val,x,t[id].ch[0]);
		upd(id);
		return;
	}
	return;
}
inline int merge(int x,int y){
	if((!x)||(!y)){
		return (x+y);
	}
	if(t[x].rnd<=t[y].rnd){
		t[x].ch[1]=merge(t[x].ch[1],y);
		upd(x);
		return x;
	}else{
		t[y].ch[0]=merge(x,t[y].ch[0]);
		upd(y);
		return y;
	}
}

inline int rnk(int& id,int val){
    int x,y;
    split(id, val-1, x, y);
    int k = t[x].siz+1;
    id = merge(x,y);
    return k;
}

inline void _ins(int& id,int k){
	int u,v;
	split(id,k,u,v);
	id=merge(merge(u,nnode(k)),v);
	return;
}
inline void _del(int& id,int k){
	int u,v,w;
	split(id,k,v,w);
	split(v,k-1,u,v);
	v=merge(t[v].ch[0],t[v].ch[1]);
	id=merge(u,merge(v,w));
	return;
}

void del(int x,int l,int r,int pos,int k){
	_del(seg[x],k);
	if(l==r){
		return;	
	}
	int mid=(l+r)>>1;
	if(pos<=mid){
		del((x<<1),l,mid,pos,k);
	}else{
		del((x<<1)|1,mid+1,r,pos,k);
	}
	
	return;
}
void add(int x,int l,int r,int pos,int k){
	_ins(seg[x],k);
	if(l==r){
		return;	
	}
	int mid=(l+r)>>1;
	if(pos<=mid){
		add((x<<1),l,mid,pos,k);
	}else{
		add((x<<1)|1,mid+1,r,pos,k);
	}
	
	return;
}

inline int qrnk(int x,int l,int r,int tl,int tr,int k){
	if(l>=tl&&r<=tr){ 
		return rnk(seg[x],k);
	}
	int mid=(l+r)>>1;
	if(tr<=mid){
		return qrnk((x<<1),l,mid,tl,tr,k);
	}else if(tl>mid){
		return qrnk((x<<1)|1,mid+1,r,tl,tr,k);
	}else{
		return qrnk((x<<1),l,mid,tl,tr,k)+qrnk((x<<1)|1,mid+1,r,tl,tr,k)-1;
	}
	
	return 2237;
}
inline int qkth(int tl,int tr,int k){
	int al=0,ar=100000000;
	while(al<ar){
		int mid=(al+ar+1)>>1;
		int rnkm=qrnk(1,1,n,tl,tr,mid);
		if(rnkm>k){
			ar=mid-1;
		}else{
			al=mid;
		}
	}
	
	return al;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    srand(2238);
    cin>>n>>m;
	for(int i=1;i<=n;i++){
	    cin>>a[i];
	    amin=min(amin,a[i]);
	    amax=max(amax,a[i]);
		add(1,1,n,i,a[i]);
	}
	for(int i=1;i<=m;i++){
	    cin>>rop;
		if(rop==1){
		    cin>>rl>>rr>>rk;
			printf("%d\n",qrnk(1,1,n,rl,rr,rk));
		}else if(rop==2){
		    cin>>rl>>rr>>rk;
			printf("%d\n",qkth(rl,rr,rk));
		}else if(rop==3){
		    cin>>rpos>>rk;
			del(1,1,n,rpos,a[rpos]);
			add(1,1,n,rpos,rk);
	        amin=min(amin,a[i]);
	        amax=max(amax,a[i]);
			a[rpos]=rk;
		}else if(rop==4){
		    cin>>rl>>rr>>rk;
			int rkk=qrnk(1,1,n,rl,rr,rk);
			if(rkk==1){
				printf("-2147483647\n");
			}else{
				printf("%d\n",qkth(rl,rr,rkk-1));
			}
		}else{
		    cin>>rl>>rr>>rk;
			int rkk=qrnk(1,1,n,rl,rr,rk+1);
			if(rkk>rr-rl+1){
				printf("2147483647\n");
			}else{
				printf("%d\n",qkth(rl,rr,rkk));
			}
		}
	}
	
	return 0;
} 

标签:rr,树套,int,cin,笔记,else,学习,rl,rk
From: https://www.cnblogs.com/rdfzchenyy/p/node-tree-tree.html

相关文章

  • vivado 教程笔记 -创建工程 - 编译 - 布局布线 - 生成bit - 下板验证
    1、创建工程工程就算创建完了。2、 创建源文件双击打开后,就可以敲入代码 3、语法编译、布局布线、IO配置约束输入完一个完整代码后,先对语法进行综合分析,可直接跳过RTLANALYSIS,直接点击SYNTHESIS(综合)进行布局布线布局布线完后,IO管脚配置约束有时......
  • 聊聊多任务学习
    最近翻译的一篇分享中,主要讲解了多任务学习的各个方面,很多的专业术语与概念都不清楚,因此简单的整理了下相关的知识,做个笔记。概述现在大多数机器学习任务都是单任务学习。对于复杂的问题,也可以分解为简单且相互独立的子问题来单独解决,然后再合并结果,得到最初复杂问题的结果。这......
  • 学习笔记-计算机病毒对抗技术-病毒概述
    本周我们学习下计算机病毒揭秘与对抗技术。主要分为6大模块计算机病毒概念定义计算机病毒(ComputerVirus)指编制者在计算机程序中插入的破坏计算机功能或者破坏数据,影响计算机正常使用并且能够自我复制的一组计算机指令或程序代码。特点1、破坏性2、隐蔽性3、潜伏性4、传染性5、不可......
  • linux学习 Centos 7(一)
    linux学习Centos7(一)java学习:JaveSE、MySQL、前端(HTML、CSS、JS)、JavaWeb、SSM框架(基础)、Springboot、Vue、SpringCloud消息队列(Kafka、RabbitMQ、RockeetMQ),缓存(Redis),搜索引擎(ES),集群分布式!Linux(Centos7)的学习之路Linux一切皆文件,文件操作包括读、写、权限入门概述为什么......
  • Lnton羚通智能分析算法道路病害识别监测系统,使用CNN网络深度学习算法
    道路病害识别监测系统通过CNN网络深度学习算法,道路病害识别监测对巡检车上实时监控道路影像数据进行分析,输出道路病害裂缝巡检报告并落图展示。卷积神经网络(ConvolutionalNeuralNetwork,CNN)在图像处理和图像识别任务中取得了很大的成功。它通过卷积层、池化层和全连接层的组......
  • 网络流学习笔记
    开个坑,是个大工程,一篇可能放不下,所以后续存在形式未知。每周日写一个小时,大概会写很久,目前处于一个咕咕的状态。笔者是主要从Alex_wei的博客中学习网络流,因此本文有很多东西来自wls的博客,wlstql。1.一些有关概念网络是一张有向图\(G=(V,E)\),每条边\((u,v)\)具有流量......
  • Lnton羚通智能分析算法灭火器摆放识别检测算法, 使用python+yolo网络深度学习技术
    灭火器摆放识别检测算法通过python+yolo网络深度学习技术,自动对指定区域灭火器是否缺失进行识别,如果没有检测到指定区域有灭火器,立即抓拍存档进行告警。YOLO系列算法是一类典型的one-stage目标检测算法,其利用anchorbox将分类与目标定位的回归问题结合起来,从而做到了高效、灵活和......
  • KDT学习笔记
    这次稍微水了点。todo:复杂度。不知道是否存在的二进制分组优化。偏序问题一般是CDQ,常数小;或者可持久化,拿来做区间问题;万能的树套树,就是吃空间。然后就是KDT,多位偏序无脑叠,空间线性,时间……玄学。有时也有更好的方法,比如用std::bitset优化偏序,不过量有限,而且我不会。......
  • 02Java学习_注意事项和学习方法
    02_Java开发注意事项细节和学习方法注意事项.java是Java文件的拓展名。源文件的基本组成部分是类--class。Java程序的执行入口是main方法,固有的书写格式为:publicstaticvoidmain(String[]args){......}java语言严格区分大小写。Java方法由一条条语句......
  • *【学习笔记】(21) Prufer 序列
    Prufer序列Prufer序列可以将一个带标号\(n\)个节点的树用\([1,n]\)中的\(n-2\)个整数表示,即\(n\)个点的完全图的生成树与长度为\(n-2\)值域为\([1,n]\)的数列构成的双射。Prufer序列可以方便的解决一类树相关的计数问题,比如凯莱定理:\(n\)个点的完全图的生成树有......