#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#define LL long long
#define LDB long double
using namespace std; LDB alpha=0.75;
const LL mo=;
int newadd;
int root=,datcnt,rbcnt,cnt,nodeintree,delnode;
char ans[];
int nd[],nex[];
int rb[];
LL key[]; struct treenode{
int size,lc,rc,num,fa,tim,v,dep;
LL nam; inline bool operator < (const treenode&a) const {
if (num<a.num) return();
if (num>a.num) return();
if (tim>a.tim) return();
return();
} inline bool operator == (const treenode&a) const{
if ((a.num==num)&&(a.tim==tim)&&(a.nam==nam)) return();
return();
}
}tr[],dat[]; LL namhash(char* st){
LL t=,len=strlen(st);
for (int i=;i<len;i++)
t*=,t+=st[i]-'A'+;
return(t);
} int numget(char* st){
int t=,len=strlen(st);
for (int i=;i<len;i++) t*=,t+=st[i]-'';
return(t);
} void namtrans(LL nam){
int cnt=-;LL t=;
while (t<=nam)
t*=,cnt+=; for (int i=cnt;i>=;i--) ans[i]=nam%+'A'-,nam/=;
for (int i=;i<=cnt;i++) putchar(ans[i]);
} int hash_query(LL nam){
int po=nam%mo;
for (int p=nd[po];p!=-;p=nex[p])
if (key[p]==nam) return(p);
nex[++datcnt]=nd[po];nd[po]=datcnt;key[datcnt]=nam;
newadd=;
return(datcnt);
} int getrank(int po,treenode t){
if ((t==tr[po])&&(tr[po].v!=)) return(tr[tr[po].lc].size+tr[po].v);
if (t<tr[po]) return(getrank(tr[po].lc,t));
if (tr[po]<t) return(getrank(tr[po].rc,t)+tr[tr[po].lc].size+tr[po].v);
} LL getkth(int po,int num){
if (num<=tr[tr[po].lc].size) return(getkth(tr[po].lc,num));
if (num>tr[tr[po].lc].size+tr[po].v) return(getkth(tr[po].rc,num-tr[tr[po].lc].size-tr[po].v));
return(tr[po].nam);
} void dfs(int po){
if (tr[po].lc) dfs(tr[po].lc);
if (tr[po].v) rb[++rbcnt]=po;else nodeintree--,delnode--;
if (tr[po].rc) dfs(tr[po].rc);
} void build(int l,int r){
int mid=(l+r)>>,po=rb[(l+r)/]; if (l<mid){
tr[po].lc=rb[(l+mid-)/];
tr[rb[(l+mid-)/]].fa=po;
tr[rb[(l+mid-)/]].dep=tr[po].dep+;
build(l,mid-);
}else tr[po].lc=;
if (r>mid){
tr[po].rc=rb[(r+mid+)/];
tr[rb[(r+mid+)/]].fa=po;
tr[rb[(r+mid+)/]].dep=tr[po].dep+;
build(mid+,r);
}else tr[po].rc=;
tr[po].size=tr[tr[po].lc].size+tr[tr[po].rc].size+tr[po].v;
} void rebuild(int po){
rbcnt=;dfs(po); if (po!=root){
tr[rb[(rbcnt+)/]].fa=tr[po].fa;
tr[rb[(rbcnt+)/]].dep=tr[tr[po].fa].dep+;
if (po==tr[tr[po].fa].lc) tr[tr[po].fa].lc=rb[(rbcnt+)/];
else tr[tr[po].fa].rc=rb[(rbcnt+)/];
}else {root=rb[(rbcnt+)/];tr[rb[(rbcnt+)/]].fa=;tr[rb[(rbcnt+)/]].dep=;} build(,rbcnt);
} void scapegoat_insert(int num){
nodeintree++;
if ((tr[root].size==)&&(tr[root].lc==)&&(tr[root].rc==)) {
root=++cnt;tr[root]=dat[num];tr[root].dep=;
tr[cnt].v=;tr[cnt].size=;
return;
}
int po=root;
while (){
tr[po].size++; if (dat[num]==tr[po]) {tr[po].v++;break;} if (dat[num]<tr[po]){
if (tr[po].lc==){
tr[++cnt]=dat[num];
tr[cnt].fa=po;
tr[po].lc=cnt;
tr[cnt].dep=tr[po].dep+;
tr[cnt].v=;tr[cnt].size=;
break;
}else {po=tr[po].lc;continue;}
} if (tr[po]<dat[num]){
if (tr[po].rc==){
tr[++cnt]=dat[num];
tr[cnt].fa=po;
tr[po].rc=cnt;
tr[cnt].dep=tr[po].dep+;
tr[cnt].v=;tr[cnt].size=;
break;
}else {po=tr[po].rc;continue;}
}
} if (tr[po].dep>(log(tr[root].size)/log(/alpha))){
int dp=tr[po].dep;
while ((dp-tr[po].dep)<=(log(tr[po].size)/log(/alpha))) po=tr[po].fa;
rebuild(po);
}
} void scapegoat_delete(int num){
int po=root;
while (){
tr[po].size--;
if (tr[po]<dat[num]) {po=tr[po].rc;continue;}
if (dat[num]<tr[po]) {po=tr[po].lc;continue;}
if (tr[po]==dat[num]) {tr[po].v--;if (tr[po].v==) delnode++;break;}
}
if (delnode>nodeintree/) rebuild(root);
} int main(){ freopen("a.in","r",stdin); int n;char st[];
scanf("%d",&n); for (int i=;i<=;i++) nd[i]=-; for (int i=;i<=n;i++){
scanf("%s",st); if (st[]=='+'){
LL nam=namhash(st);
newadd=;
int po=hash_query(nam);
if (!newadd) {
scapegoat_delete(po);
dat[po].nam=nam;scanf("%d",&dat[po].num);dat[po].tim=i;
scapegoat_insert(po);
}else{
dat[po].nam=nam;scanf("%d",&dat[po].num);dat[po].tim=i;
scapegoat_insert(po);
}
} if ((st[]=='?')&&(st[]<='Z')&&(st[]>='A')){
LL nam=namhash(st);
int po=hash_query(nam);
printf("%d\n",datcnt-getrank(root,dat[po])+);
} if ((st[]=='?')&&(st[]<='')&&(st[]>='')){
int po=numget(st);
for (int i=po;i<=min(po+,datcnt);i++) {
namtrans(getkth(root,datcnt-i+));
if (i!=min(po+,datcnt))printf(" ");
}
printf("\n");
}
}
}

替罪羊树模板(BZOJ1056/1862)的更多相关文章

  1. [luogu3369]普通平衡树(替罪羊树模板)

    解题关键:由于需要根据平衡进行重建,所以不能进行去重,否则无法保证平衡性. #include<cstdio> #include<cstring> #include<alg ...

  2. [TYVJ1728/BZOJ3224]普通平衡树-替罪羊树

    Problem 普通平衡树 Solution 本题是裸的二叉平衡树.有很多种方法可以实现.这里打的是替罪羊树模板. 此题极其恶心. 前驱后继模块需要利用到rank模块来换一种思路求. 很多细节的地方容 ...

  3. 「BZOJ3600」没有人的算术 替罪羊树+线段树

    题目描述 过长--不想发图也不想发文字,所以就发链接吧-- 没有人的算术 题解 \(orz\)神题一枚 我们考虑如果插入的数不是数对,而是普通的数,这就是一道傻题了--直接线段树一顿乱上就可以了. 于 ...

  4. 平衡树简单教程及模板(splay, 替罪羊树, 非旋treap)

    原文链接https://www.cnblogs.com/zhouzhendong/p/Balanced-Binary-Tree.html 注意是简单教程,不是入门教程. splay 1. 旋转: 假设 ...

  5. 替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 闲的没事,把各种平衡树都写写 比较比较... 下面是替罪羊树 #include <cstdio> #inc ...

  6. [模板] 平衡树: Splay, 非旋Treap, 替罪羊树

    简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...

  7. 替罪羊树&&非旋treap

    题解: 替罪羊树的模板和splay差距还是比较大的.. 按照我的splay的写法 真是都是问题.. 替罪羊树就是暴力的搞 当某颗子树大小大于这棵树的alpha时 就退出 另外删除的时候打懒标记删除 当 ...

  8. 平衡树及笛卡尔树讲解(旋转treap,非旋转treap,splay,替罪羊树及可持久化)

    在刷了许多道平衡树的题之后,对平衡树有了较为深入的理解,在这里和大家分享一下,希望对大家学习平衡树能有帮助. 平衡树有好多种,比如treap,splay,红黑树,STL中的set.在这里只介绍几种常用 ...

  9. Luogu 3369 / BZOJ 3224 - 普通平衡树 - [替罪羊树]

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 https://www.luogu.org/problemnew/show/P3 ...

随机推荐

  1. hdu 3472 HS BDC(混合路的欧拉路径)

    这题是混合路的欧拉路径问题. 1.判断图的连通性,若不连通,无解. 2.给无向边任意定向,计算每个结点入度和出度之差deg[i].deg[i]为奇数的结点个数只能是0个或2个,否则肯定无解. 3.(若 ...

  2. ubuntu编译最新版本WebKit

    好久都没更新webkit 源码在ubuntu上编译了,网上搜了一下,基本上都是早期编译的webkit版本.可能是大家都去搞高大上的谷歌浏览器了吧. 今天就以ubuntu14.04版本作为编译环境来讲讲 ...

  3. PHP&MySQL(二)——困也得啃书

    madan,所有事情都敢赶在一起...以后每天中午去学车啊,好开心..晚上好困,但是困也得啃书........ 二.PHP脚本编程语言 什么变量啊,数据类型啊,特别特别基本的不记录了,说点容易忽略的. ...

  4. Stanford机器学习笔记-4. 神经网络Neural Networks (part one)

    4. Neural Networks (part one) Content: 4. Neural Networks (part one) 4.1 Non-linear Classification. ...

  5. docker-image container 基本操作 -常用命令

    基本概念: container 容器.可以把每个 container 看做是一个独立的主机. container 的创建通常有一个 image 作为其模板.类比成虚拟机的话可以理解为 image 就是 ...

  6. 洛谷八月月赛Round1凄惨记

    个人背景: 上午9:30放学,然后因为学校举办读书工程跟同学去书城选书,中午回来开始打比赛,下午又回老家,中间抽出一点时间调代码,回家已经8:50了 也许是7月月赛时“连蒙带骗”AK的太幸运然而因同学 ...

  7. Unity 碰撞器

    Unity引擎的碰撞器 常见的有Box Collider,Capsule Collider等等 IsTrigger(触发器) 在这些碰撞器中有一个属性 Is Trigger(是否使用触发器) 触发器事 ...

  8. [No000005]C#注册表操作,创建,删除,修改,判断节点是否存在

    //用.NET下托管语言C#操作注册表,主要内容包括:注册表项的创建,打开与删除.键值的创建(设置值.修改),读取和删除.判断注册表项是否存在.判断键值是否存在. //准备工作: //1:要操作注册表 ...

  9. strcmp()&&mb_ereg_replace()&&ereg()

    主要记录两个函数,一个是strcmp(),一个是mb_ereg_replace() strcmp() php 5.3 以后字符串和数组比较会返回0 测试代码: PHP <?php $passwo ...

  10. 省选模拟赛 project

    solution: 最小割问题. 建如下边: (S,i,Ai)代表选用A语言编写第i个项目: (i,T,Bi)代表选用A语言编写第i个项目: 其后注意要反向连边 (i,j,D)代表选用B语言编写第i个 ...