替罪羊树模板(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 ...
随机推荐
- CentOS6 Shell脚本/bin/bash^M: bad interpreter错误解决方法
在windows下保存了一个脚本文件,用ssh上传到centos,添加权限执行nginx提示没有那个文件或目录.shell脚本放到/etc/init.d/目录下,再执行/etc/init.d/ngin ...
- 烂泥:ubuntu下vsftpd虚拟用户配置
本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我微信ilanniweb. 以前搭建vsftpd都是在centos下,本以为在ubuntu按照以前的步骤搭建即可.可 ...
- centos 安装依赖错误
出现下列错误: error: curl/curl.h: No such file or directory 出错原因:缺少libcurl-dev or libcurl-devel centOS上安装依 ...
- oracle操作之传输表空间
一.传输表空间概述 什么是传输表空间,传输表空间技术始于oracle9i,不论是数据字典管理的表空间还是本地管理的表空间,都可以使用传输表空间技术:传输表空间不需要在源数据库和目标数据库之间具有同样的 ...
- Django初体验(一):自定义表单提交
注:本人使用的Django1.8.3版本进行测试 除了使用Django内置表单,有时往往我们需要自定义表单.对于自定义表单Post方式提交往往会带来由CSRF(跨站请求伪造)产生的错误"CS ...
- [译] OpenStack Kilo 版本中 Neutron 的新变化
OpenStack Kilo 版本,OpenStack 这个开源项目的第11个版本,已经于2015年4月正式发布了.现在是个合适的时间来看看这个版本中Neutron到底发生了哪些变化了,以及引入了哪些 ...
- 使用jquery合并表格中相同文本的相邻单元格
一.效果 二.代码 <!DOCTYPE HTML> <html> <head> <title>Example</title> <met ...
- [转]asp.net c# 网上搜集面试题目(附答案)
本文转自:http://www.cnblogs.com/hndy/articles/2234188.html 1.String str=new String("a")和String ...
- 最短路问题Dijkstra算法
Dijkstra算法可以解决源点到任意点的最短距离并输出最短路径 准备: 建立一个距离数组d[ n ],记录每个点到源点的距离是多少 建立一个访问数组v[ n ],记录每个点是否被访问到 建立一个祖先 ...
- namesilo域名注册教程
一.注册账号 打开http://www.namesilo.com ,我们先去注册一个Namesilo帐号,然后再在Namesilo注册域名!如图: 接下来,就是填写一些简单资料,如图: 然后Names ...