[namespace hdk] Balanced_tree 整合
代码
#include<bits/stdc++.h>
using namespace std;
namespace hdk{
namespace balanced_tree{
const int N=2000001,inf=114514191;
class splay{
private:
int root,tot;
struct tree{
int w;
int cnt,size;
int fa,son[2];
}t[N];
public:
tree *operator [](int x){
return &t[x];
}
inline int getroot(){
return root;
}
inline void clear(int x){
t[x]={0,0,0,0,{0,0}};
}
inline bool judgeson(int x){
return t[t[x].fa].son[1]==x;
}
inline void update(int x){
if(x){
t[x].size=t[x].cnt;
if(t[x].son[0]) t[x].size+=t[t[x].son[0]].size;
if(t[x].son[1]) t[x].size+=t[t[x].son[1]].size;
}
}
inline void rotate(int x){
int f=t[x].fa,gf=t[f].fa;
int k=judgeson(x);
t[f].son[k]=t[x].son[k^1];
t[t[f].son[k]].fa=f;
t[x].son[k^1]=f;
t[f].fa=x;
t[x].fa=gf;
if(gf){
t[gf].son[t[gf].son[1]==f]=x;
}
update(f);update(x);
}
inline void sply(int x){
for(int f;(f=t[x].fa);rotate(x)){
if(t[f].fa){
if(judgeson(x)==judgeson(f)){
rotate(f);
}
else rotate(x);
}
}
root=x;
}
inline void insert(int x){
if(!root){
tot++;
t[tot]={x,1,1,0,{0,0}};
root=tot;
return;
}
int now=root,fa=0;
while(1){
if(x==t[now].w){
t[now].cnt++;
update(now);update(fa);
sply(now);
break;
}
fa=now;
now=t[now].son[t[now].w<x];
if(!now){
tot++;
t[tot]={x,1,1,fa,{0,0}};
t[fa].son[t[fa].w<x]=tot;
update(fa);
sply(tot);
break;
}
}
}
inline int findnum(int x){
int now=root;
while(now){
if(t[now].son[0] and x<=t[t[now].son[0]].size){
now=t[now].son[0];
}
else{
int temp=t[now].cnt;
if(t[now].son[0]){
temp+=t[t[now].son[0]].size;
}
if(x<=temp) return t[now].w;
x-=temp;
now=t[now].son[1];
}
}
return t[now].w;
}
inline int findrank(int x){
int now=root,ans=0;
while(now){
if(x<t[now].w){
now=t[now].son[0];
}
else{
if(t[now].son[0]){
ans+=t[t[now].son[0]].size;
}
if(x==t[now].w){
sply(now);
return ans+1;
}
ans+=t[now].cnt;
now=t[now].son[1];
}
}
return ans+1;
}
inline int findpre(){
int now=t[root].son[0];
while(t[now].son[1]) now=t[now].son[1];
return now;
}
inline int findnext(){
int now=t[root].son[1];
while(t[now].son[0]) now=t[now].son[0];
return now;
}
inline void remove(int x){
findrank(x);
if(t[root].cnt>1){
t[root].cnt--;
update(root);
return;
}
if(!t[root].son[0] and !t[root].son[1]){
clear(root);
root=0;
return;
}
if(!t[root].son[0]){
int oroot=root;
root=t[root].son[1];
t[root].fa=0;
clear(oroot);
return;
}
else if(!t[root].son[1]){
int oroot=root;
root=t[root].son[0];
t[root].fa=0;
clear(oroot);
return;
}
int left=findpre(),oroot=root;
sply(left);
t[root].son[1]=t[oroot].son[1];
t[t[oroot].son[1]].fa=root;
clear(oroot);
update(root);
}
inline int findpre(int x){
insert(x);
int ans=t[findpre()].w;
remove(x);
return ans;
}
inline int findnext(int x){
insert(x);
int ans=t[findnext()].w;
remove(x);
return ans;
}
inline tree* get(int id){
return &t[id];
}
};
class treap{
private:
int tot;
struct tree{
int w,data,size,cnt,son[2];
}t[N];
int root;
public:
tree *operator [](int x){
return &t[x];
}
inline int getroot(){
return root;
}
inline int size(){
return tot;
}
inline void update(int x){
t[x].size=t[t[x].son[0]].size+t[t[x].son[1]].size+t[x].cnt;
}
inline int newnode(int val){
t[++tot]={val,rand(),1,1,{0,0}};
return tot;
}
inline tree* get(int id){
return &t[id];
}
inline void rotate(int &id,int isrignt){
bool k=isrignt;
int temp=t[id].son[k^1];
t[id].son[k^1]=t[temp].son[k];
t[temp].son[k]=id;
id=temp;
update(t[id].son[k]);
update(id);
}
inline void insert(int &id,int x){
if(!id){
id=newnode(x);
return;
}
if(x==t[id].w) t[id].cnt++;
else{
bool k=(x>=t[id].w);
insert(t[id].son[k],x);
if(t[id].data<t[t[id].son[k]].data){
rotate(id,k^1);
}
}
update(id);
}
inline void remove(int &id,int x){
if(!id) return;
if(t[id].w==x){
if(t[id].cnt>1){
t[id].cnt--;
update(id);
return;
}
if(t[id].son[0] or t[id].son[1]){
if(!t[id].son[1] or t[t[id].son[0]].data>t[t[id].son[1]].data){
rotate(id,1);
remove(t[id].son[1],x);
}
else{
rotate(id,0);
remove(t[id].son[0],x);
}
update(id);
}
else{
id=0;
}
return;
}
(x<t[id].w)?remove(t[id].son[0],x):remove(t[id].son[1],x);
update(id);
}
inline int getrank(int id,int x){
if(!id){
return 1;
}
if(x==t[id].w){
return t[t[id].son[0]].size+1;
}
else if(x<t[id].w){
return getrank(t[id].son[0],x);
}
else{
return t[t[id].son[0]].size+t[id].cnt+getrank(t[id].son[1],x);
}
}
inline int getval(int id,int rank){
if(!id) return inf;
if(rank<=t[t[id].son[0]].size){
return getval(t[id].son[0],rank);
}
else if(rank<=t[t[id].son[0]].size+t[id].cnt){
return t[id].w;
}
else{
return getval(t[id].son[1],rank-t[t[id].son[0]].size-t[id].cnt);
}
}
inline int findpre(int x){
int id=root,pre=0;
while(id){
if(t[id].w<x){
pre=t[id].w;
id=t[id].son[1];
}
else{
id=t[id].son[0];
}
}
return pre;
}
inline int findnext(int x){
int id=root,next=0;
while(id){
if(t[id].w>x){
next=t[id].w;
id=t[id].son[0];
}
else{
id=t[id].son[1];
}
}
return next;
}
inline void insert(int x){
insert(root,x);
}
inline void remove(int x){
remove(root,x);
}
inline int findrank(int x){
return getrank(root,x);
}
inline int findnum(int rank){
return getval(root,rank);
}
};
class fhq_treap{
private:
int tot,removed;
struct tree{
int w,data,size,cnt,son[2];
}t[N];
int root;
public:
tree *operator [](int x){
return &t[x];
}
inline int getroot(){
return root;
}
inline int size(){
return tot;
}
tree *get(int id){
return &t[id];
}
inline void update(int x){
t[x].size=1+t[t[x].son[0]].size+t[t[x].son[1]].size;
}
inline int newnode(int val){
t[++tot]={val,rand(),1,1,{0,0}};
return tot;
}
inline int merge(int x,int y){
if(!x or !y) return x+y;
if(t[x].data<t[y].data){
t[x].son[1]=merge(t[x].son[1],y);
update(x);
return x;
}
else{
t[y].son[0]=merge(x,t[y].son[0]);
update(y);
return y;
}
}
inline void split(int now,int k,int &x,int &y){
if(!now) x=y=0;
else{
if(t[now].w<=k){
x=now;
split(t[now].son[1],k,t[now].son[1],y);
}
else{
y=now;
split(t[now].son[0],k,x,t[now].son[0]);
}
update(now);
}
}
inline int find(int now,int rank){
while(1){
if(rank<=t[t[now].son[0]].size){
now=t[now].son[0];
}
else if(rank==t[t[now].son[0]].size+1){
return now;
}
else{
rank-=t[t[now].son[0]].size+1;
now=t[now].son[1];
}
}
}
inline void insert(int x){
int a,b;
split(root,x,a,b);
root=merge(merge(a,newnode(x)),b);
}
inline void remove(int a){
int x,y,z;
split(root,a,x,z);
split(x,a-1,x,y);
y=merge(t[y].son[0],t[y].son[1]);
root=merge(merge(x,y),z);
}
inline int findrank(int a){
int x,y;
split(root,a-1,x,y);
int ans=t[x].size+1;
root=merge(x,y);
return ans;
}
inline int findnum(int rank){
return t[find(root,rank)].w;
}
inline int findpre(int a){
int x,y;
split(root,a-1,x,y);
int ans=t[find(x,t[x].size)].w;
root=merge(x,y);
return ans;
}
inline int findnext(int a){
int x,y;
split(root,a,x,y);
int ans=t[find(y,1)].w;
root=merge(x,y);
return ans;
}
};
}
}
P6136 使用例
#include<bits/stdc++.h>
using namespace std;
using namespace hdk::balanced_tree;
using namespace hdk::fastio; //详见demap合集
#define int long long
fhq_treap s;//可直接更改树名:treap / splay
int n,m,op,x,last,ans;
signed main(){
srand(time(0));
n=read(),m=read();
for(int i=1;i<=n;++i){
x=read();
s.insert(x);
}
while(m--){
op=read(),x=read();
x^=last;
if(op==1){
s.insert(x);
}
if(op==2){
s.remove(x);
}
if(op==3){
last=s.findrank(x);
ans^=last;
}
if(op==4){
last=s.findnum(x);
ans^=last;
}
if(op==5){
last=s.findpre(x);
ans^=last;
}
if(op==6){
last=s.findnext(x);
ans^=last;
}
}
w(ans);
}
[namespace hdk] Balanced_tree 整合的更多相关文章
- springcloud必知功能使用教程
springcloud Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载均衡.断路 ...
- spring 与 CXF 整合 webservice 出现error “Unable to locate Spring NamespaceHandler for XML schema namespace” 总结
我试了多个版本的spring 发现 出现error : Unable to locate Spring NamespaceHandler for XML schema namespace 并非都是sp ...
- SSH整合:Unable to instantiate Action, employeeAction, defined for 'emp-list' in namespace '/'employeeAction - action
SSH整合,照着视频敲的,不知为何会报错,经历了快两周的折磨给解决了.记录下来给后面需要帮助的人,也算极好的了. Struts Problem Report Struts has detected a ...
- SSH整合报错:Unable to instantiate Action, testAction, defined for 'test' in namespace '/'testAction
报错如下: Struts Problem Report Struts has detected an unhandled exception: Messages: testAction Unable ...
- 整合mybatis时报错:Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/tx]
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Una ...
- spring源码分析之freemarker整合
FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页.电子邮件.配置文件.源代码等)的通用工具. 它不是面向最终用户的,而是一个Java类库,是一款程 ...
- SSH框架整合(代码加文字解释)
一.创建数据库并设置编码. A) create database oa default character set utf8. 二.MyEclipse工程 A) 在Myeclipse里创建web工程, ...
- Eclipse Meaven Spring SpringMVC Mybaits整合
本示例是在:Ubuntu15上实现的:Windows上安装Maven将不太相同. Maven Install Run command sudo apt-get install maven, to in ...
- struts2+hibernate整合-实现登录功能
最近一直学习struts2+hibernate框架,于是想把两个框架整合到一起,做一个小的登录项目.其他不多说,直接看例子. 1).Struts2 和hibernate的环境配置 包括jar包.web ...
- Spring,Mybatis 整合Memcache
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.Memcached ...
随机推荐
- 前端说你的API接口太慢了,怎么办?
当有千万条海量数据时,前端调取接口发现接口响应的太慢,前端这时让你优化一下接口,你说有几千万条数据,觉得自己尽力了,前端觉得你好菜,别急,读完这篇文章,让前端喊你一声:大佬,厉害!!! 常用的方法总结 ...
- 新年切红包-scratch小游戏
程序说明: <新年切红包>是一款Scratch制作的小游戏,灵感来源于流行的切水果游戏.在这个游戏中,玩家需要用鼠标切割屏幕上不断飞出的红包,切割到红包将获得金币奖励,而切割到爆竹则会导致 ...
- 【Hibernate】05 缓存与MySQL事务隔离
Cache 什么是缓存? 数据存储到数据库,是从内存中以流的方式写进[输出]到数据库,其效率并不是很高 - 所以在内存中暂存一部分数据,可以不以流的方式读取,效率是非常高的[相对于流来说] Hiber ...
- 汽车模具设计软件 —— 达索集团的Catia
相关: https://www.3ds.com/zh/products-services/catia/ Catia是Dassault Systems公司推出的产品造型软件,广泛应用于汽车.航空.机械等 ...
- 论文《policy-gradient-methods-for-reinforcement-learning-with-function-approximation 》的阅读——强化学习中的策略梯度算法基本形式与部分证明
最近组会汇报,由于前一阵听了中科院的教授讲解过这篇论文,于是想到以这篇论文为题做了学习汇报.论文<policy-gradient-methods-for-reinforcement-learni ...
- 【转载】 python进程绑定CPU
版权声明:本文为CSDN博主「人间再无张居正」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/u01388765 ...
- SMU Summer 2024 Contest Round 2
SMU Summer 2024 Contest Round 2 Sierpinski carpet 题意 给一个整数 n ,输出对应的 \(3^n\times 3^n\) 的矩阵. 思路 \(n = ...
- 代码随想录Day16
513.找树左下角的值 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值. 假设二叉树中至少有一个节点. 示例 1: 输入: root = [2,1,3] 输出: 1 示 ...
- mongodb 中嵌套数组的且查询
如果在mongodb中存在如下数据 { audit:{ experts:[{expertId:"1",result:"success",......} {exp ...
- Python 潮流周刊#66:Python 的预处理器(摘要)
本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...