替罪羊树模板(BZOJ1056/1862)
#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)的更多相关文章
- [luogu3369]普通平衡树(替罪羊树模板)
解题关键:由于需要根据平衡进行重建,所以不能进行去重,否则无法保证平衡性. #include<cstdio> #include<cstring> #include<alg ...
- [TYVJ1728/BZOJ3224]普通平衡树-替罪羊树
Problem 普通平衡树 Solution 本题是裸的二叉平衡树.有很多种方法可以实现.这里打的是替罪羊树模板. 此题极其恶心. 前驱后继模块需要利用到rank模块来换一种思路求. 很多细节的地方容 ...
- 「BZOJ3600」没有人的算术 替罪羊树+线段树
题目描述 过长--不想发图也不想发文字,所以就发链接吧-- 没有人的算术 题解 \(orz\)神题一枚 我们考虑如果插入的数不是数对,而是普通的数,这就是一道傻题了--直接线段树一顿乱上就可以了. 于 ...
- 平衡树简单教程及模板(splay, 替罪羊树, 非旋treap)
原文链接https://www.cnblogs.com/zhouzhendong/p/Balanced-Binary-Tree.html 注意是简单教程,不是入门教程. splay 1. 旋转: 假设 ...
- 替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 闲的没事,把各种平衡树都写写 比较比较... 下面是替罪羊树 #include <cstdio> #inc ...
- [模板] 平衡树: Splay, 非旋Treap, 替罪羊树
简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...
- 替罪羊树&&非旋treap
题解: 替罪羊树的模板和splay差距还是比较大的.. 按照我的splay的写法 真是都是问题.. 替罪羊树就是暴力的搞 当某颗子树大小大于这棵树的alpha时 就退出 另外删除的时候打懒标记删除 当 ...
- 平衡树及笛卡尔树讲解(旋转treap,非旋转treap,splay,替罪羊树及可持久化)
在刷了许多道平衡树的题之后,对平衡树有了较为深入的理解,在这里和大家分享一下,希望对大家学习平衡树能有帮助. 平衡树有好多种,比如treap,splay,红黑树,STL中的set.在这里只介绍几种常用 ...
- Luogu 3369 / BZOJ 3224 - 普通平衡树 - [替罪羊树]
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3224 https://www.luogu.org/problemnew/show/P3 ...
随机推荐
- 四、Android学习第四天——JAVA基础回顾(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 四.Android学习第四天——JAVA基础回顾 这才学习Android的 ...
- linux mount 硬盘挂载和卸载
Linux 挂载 [root@whp6 ~]# mount /dev/sdb5 /mnt/ [root@whp6 ~]# df -h Filesystem Size Used Avail Use% M ...
- PowerDesigner新装后的设置
1.设置name不自动等于code 1.1菜单栏选择tools,选择general Options,打开如图1所示界面 1.2选择Dialog,勾掉红框中复选框,点OK即可
- stm32 中断几个库函数实现过程分析
感谢原文作者:鱼竿的传说,这篇文章写得不错,转载自 http://www.cnblogs.com/chineseboy/archive/2013/03/14/2956782.html 前题: 闭门造车 ...
- 自定义评分器Similarity,提高搜索体验(转)
文章转自:http://blog.csdn.net/duck_genuine/article/details/6257540 首先说一下lucene对文档的评分规则: score(q,d) = ...
- Android中常用的布局
一般分为5大类. Android中所有的空间第一字母都是大写 1.线性布局 LinearLayout 2.相对布局 RelativeLayout 3.帧布局--分层显示 FrameLayout 4. ...
- hdu 1166
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- Oracle Delete inner的方式,级联删除子表的数据方式。
例子1: from table2 b where a.id=b.id) 例子2: rebatepolicy表是主表,rebatepolicyitems是从表,从表有主表的主键,现在对于主表一些条件的数 ...
- window.execScript的兼容性写法
把探嗅浏览器的操作提前到代码加载的时候,在代码加载的时候就立刻进行一次判断,以便让globalEval返回一个包裹了正确逻辑的函数 var globalEval = (function(){ var ...
- js删除数据的几种方法
js 删除数组几种方法 var arr=['a','b','c']; 若要删除其中的'b',有两种方法: 1.delete方法:delete arr[1] 这种方式数组长度不变,此时arr[1]变为u ...