bzoj 3217 ALOEXT 替罪羊树套trie树
感觉又刚了一遍带插入区间k小值。。。
这题写个替罪羊练一下。其实应该可以用重量平衡的treap套trie。
带插入维护一段区间的trie和次小值。
区间次小值随便维护,区间trie呢?
我会做!替罪羊套trie!
不过写到一半你会发现这题还有删除。
treap删点直接旋到下面删。那替罪羊怎么删?
直接重构?每次删中间的点就挂了。
打标记? 似乎会有很多特判。
只要像线段树一样建就好了。把所有的表示元素的点都放在叶节点,其他点都是空点。只维护子树中所有叶节点形成的trie。
插入时新建两个点,删除时直接删除叶节点。
查询时像线段树一样找到log个区间,然后类似主席树地跑。
#include <bits/stdc++.h>
using namespace std;
#define A 20
#define alp 0.93
#define N 1100000
#define M 35000000
#define ls(x) ch[x][0]
#define rs(x) ch[x][1]
#define which(x) (ch[fa[x]][1]==x)
int a[N],n,m,n0,ans;
int st[210],top;
char s[11];
struct Trie
{int ch[M][2],num[M],cnt;queue<int>q;int ap(){if(!q.empty()){int ret=q.front();q.pop();ls(ret)=rs(ret)=0;num[ret]=0;return ret;}return ++cnt;}void del(int x){if(!x)return;q.push(x);del(ls(x));del(rs(x));}void insert(int &now,int v,int deep,int tp){if(!now)now=ap();num[now]+=tp;if(deep==-1)return;if(v>>deep&1)insert(rs(now),v,deep-1,tp);else insert(ls(now),v,deep-1,tp);}int merge(int x,int y){if(!x&&!y)return 0;int ret=ap();ls(ret)=merge(ls(x),ls(y));rs(ret)=merge(rs(x),rs(y));num[ret]=num[x]+num[y];return ret;}int query(int x,int deep){if(deep<0)return 0;int t=x>>deep&1,sum=0;for(int i=1;i<=top;i++)sum+=num[ch[st[i]][t^1]];for(int i=1;i<=top;i++)st[i]=ch[st[i]][sum ? t^1:t];return query(x,deep-1)+(sum ? 1<<deep:0);}
}tr1;
struct node
{int mx,sx;node(){}node(int mx,int sx):mx(mx),sx(sx){}void ins(int x){if(x>mx)sx=mx,mx=x;else if(x>sx)sx=x;}
};
node merge(node r1,node r2)
{node ret=r1;ret.ins(r2.mx);ret.ins(r2.sx);return ret;
}
struct Sheep
{queue<int>q;int ch[N][2],size[N],root[N],fa[N],val[N],sz[N],bj[N];int cnt,rt,fre,pre,tar;node v[N],n1;int ap(){if(!q.empty()){int t=q.front();q.pop();ls(t)=rs(t)=size[t]=root[t]=fa[t]=val[t]=bj[t]=0;v[t]=node(0,0);return t;}return ++cnt;}int newnode(int x){int ret=ap();bj[ret]=1;val[ret]=x;size[ret]=sz[ret]=1;v[ret]=node(x,0);tr1.insert(root[ret],x,A,1);return ret;}void pushup(int x){size[x]=size[ls(x)]+size[rs(x)];sz[x]=size[x]+1;root[x]=tr1.merge(root[ls(x)],root[rs(x)]);v[x]=merge(v[ls(x)],v[rs(x)]);fa[ls(x)]=fa[rs(x)]=x;}int build(int l,int r){if(l>r)return 0;if(l==r)return newnode(a[l]);int mid=(l+r)>>1,ret=ap();ls(ret)=build(l,mid);rs(ret)=build(mid+1,r);pushup(ret);return ret;}void dfs(int x){if(!x)return;q.push(x);tr1.del(root[x]);if(bj[x]){a[++n]=val[x];return;}dfs(ls(x));dfs(rs(x));}void reb(int x){tr1.del(root[x]);n=0;dfs(ls(x));dfs(rs(x));int t=build(1,n);if(x==rt)rt=t;fa[t]=fa[x];ch[fa[x]][which(x)]=t;}void insert(int &now,int x,int y){if(size[now]==1||!now){int t=newnode(y),ret=ap();fa[ret]=pre;ls(ret)=t;rs(ret)=now;pushup(ret);now=ret;return;}pre=now;if(size[ls(now)]>=x)insert(ls(now),x,y);else insert(rs(now),x-size[ls(now)],y);tr1.insert(root[now],y,A,1);v[now].ins(y);size[now]++;sz[now]+=2;fa[ls(now)]=fa[rs(now)]=now;if(max(sz[ls(now)],sz[rs(now)])>sz[now]*alp)fre=now;}void del(int &now,int x){if(bj[now]){q.push(now);tar=val[now];now=0;return;}if(size[ls(now)]>=x)del(ls(now),x);else del(rs(now),x-size[ls(now)]);tr1.insert(root[now],tar,A,-1);v[now]=merge(v[ls(now)],v[rs(now)]);size[now]--;sz[now]--;fa[ls(now)]=fa[rs(now)]=now;if(max(sz[ls(now)],sz[rs(now)])>sz[now]*alp)fre=now;}void insert(int x,int y){fre=0;insert(rt,x,y);if(fre)reb(fre);}void del(int x){fre=0;del(rt,x);if(fre)reb(fre);}void find(int now,int pre,int x,int y){if(pre+1>=x&&pre+size[now]<=y){st[++top]=root[now];n1=merge(n1,v[now]);return;}if(pre+size[ls(now)]>=x)find(ls(now),pre,x,y);if(pre+size[ls(now)]<y)find(rs(now),pre+size[ls(now)],x,y);}node find(int x,int y){top=0;n1=node(0,0);find(rt,0,x,y);return n1;}
}tr2;
int main()
{scanf("%d%d",&n,&m);n0=n;for(int i=1;i<=n;i++)scanf("%d",&a[i]);tr2.rt=tr2.build(1,n);for(int x,y;m--;){scanf("%s",s);if(s[0]=='I'){scanf("%d%d",&x,&y);x=(x+ans)%n0+1;y=(y+ans)%(1<<A);n0++;tr2.insert(x,y);}else if(s[0]=='D'){scanf("%d",&x);x=(x+ans)%n0+1;n0--;tr2.del(x);}else if(s[0]=='C'){scanf("%d%d",&x,&y);x=(x+ans)%n0+1;y=(y+ans)%(1<<A);tr2.del(x);tr2.insert(x,y);}else{scanf("%d%d",&x,&y);x=(x+ans)%n0+1;y=(y+ans)%n0+1;node t=tr2.find(x,y);printf("%d\n",ans=tr1.query(t.sx,A));}}return 0;
}
bzoj 3217 ALOEXT 替罪羊树套trie树相关推荐
- 18B树、B++树和Trie树
B树.B++树和Trie树 B树 定义:一个非空M元(也称M阶)B树(R.Bayer,1970年) 满足下列条件: 1)每个结点含有m个元素a1<a2<-<am.含有m个元素的结点有 ...
- 模板:二维线段树(线段树套线段树)
文章目录 问题 解析 单点修改 询问 完整代码 标记永久化 代码 所谓二维线段树,就是有两个维度的线段树 (逃) 问题 给出一个矩形 要求支持以下操作: 1.询问一个子矩形的最值 2.修改某一个单点的 ...
- 前缀树(字典树,单词查找树,Trie树)
参考网址:https://blog.csdn.net/u013949069/article/details/78056102?utm_source=copy 概述 前缀树又名字典树,单词查找树,Tri ...
- bzoj4605 崂山白花蛇草水 权值线段树套kd树
Description Q次操作,要求资瓷 在(x,y)处放一个数字x 查询(x1,y1)到(x2,y2)矩形内第k大 Solution 非常裸的权值线段树套kd树,为了保证复杂度可以定期重构也可以平 ...
- 实现字典树(前缀树、Trie树)并详解其应用
今天看到一个比较好的数据结构,字典树,做一下记录,以供自己后期复习和读者朋友的参考. 1.定义 字典树又称单词查找树.前缀树.Trie树等,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序 ...
- 【BZOJ 4605】崂山白花蛇草水 替罪羊树套线段树
外层是借鉴了kd-tree的替罪羊里层是线段树,插入就是正常插入+拍扁重建,查询的时候,我们就像树状数组套线段树一样操作在替罪羊中找到的线段树根节点,但是对于在kd-tree查找过程中遇到的单点,我们 ...
- bzoj 3489 A simple rmq problem——主席树套线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9b ...
- 【线段树套KD树】[BZOJ4605]崂山白花蛇草水
题目描述 Description 神犇Aleph在SDOI Round2前立了一个flag:如果进了省队,就现场直播喝崂山白花蛇草水.凭借着神犇Aleph的实 力,他轻松地进了山东省省队,现在便是他履 ...
- 字典树(Trie树)的原理与实现
一.概述 1.1 基本概念 字典树,又称为单词查找树,Tire数,是一种树形结构,它是一种哈希树的变种. 1.2 基本性质 根节点不包含字符,除根节点外的每一个子节点都包含一个字符 从根节点到某一节点 ...
最新文章
- 由Python历史「解密」Python底层逻辑
- Oracle数据库几个错误
- Jensen不等式及其证明
- WIN10下怎么找到MYSQL5.7数据库中存储数据的位置以及重装mysql数据复盘
- ssh连接远程主机执行脚本的环境变量问题
- JAVA微信开源项目(jeewx)百度BAE 部署文档
- Mysql优化之索引优化
- 深度学习backbone是什么意思_CNN是靠什么线索学习到深度信息的?——一个经验性探索...
- 目标检测——YOLOv5的学习笔记
- 关于代理服务器的原理及用法
- 一个简单的轮播图代码
- Juce之旅-第一个例子(图形窗口)
- python识别文字坐标_python识别图片上的文字并返回文字在图片中的坐标
- 2022年电脑杀毒软件PK
- Bloodsucker ZOJ - 3551(期望DP)
- 人工智能笔记之专业选修课4.1.5 - 博弈论 7.极大极小策略,相关均衡
- 如何远程控制Mac电脑(MacOS下远程控制详解)
- 一种基于STM32F4的字库及图片下载方法
- 【现控】时不变连续系统
- Elementui el-select创建条目的多选下拉框 自定义校验 新增条目时字符长度限制
热门文章
- 群同态和群同构的区别_如何判断群的同态与同构
- Shader Graph 结晶体
- 解决手机设备无法adb连接
- 给宝宝早教c语言,亲爸用C语言给娃做早教,娃不耐烦的表情亮了,网友:是个高手!...
- 60个中国顶级电子技术网站
- laravel api接口+令牌认证登录
- 18-使用Selenium爬取京东商品
- python在哪些省份加入高考加分项目_Python将纳入高考?我们不妨从这几个方面分析下...
- python的前端和后端_python前端和后端数据交互,tornado框架入门,初学小试牛刀!...
- app架构升级,该如何高效实用Kotlin?架构师必备技能