爱死替罪羊树了


这种暴力的数据结构爱死了。什么?!你还不知道替罪羊树?那就看看这篇博客这篇博客吧。替罪羊树就是当不平衡时,拍扁重建,然后就平衡了。想切这道题,要先把普通平衡树那道题做了(这篇博客讲了的哦),然后就会发现,只要改一下以前的程序就可以了。这里我就着重讲下主函数怎么建树那里。

建树方法:

  1. 一开始我写的方法(指读入建树的时候),长一些,详细的都在代码里面了:
#include <bits/stdc++.h>
using namespace std;
int read(){
int ans = 0;
char ch = getchar();
while(ch > '9' || ch < '0') ch = getchar();
while(ch <= '9' && ch >= '0'){
ans = ans * 10 + ch - '0';
ch = getchar();
}
return ans;
}
struct node{
int ls , rs , f , tsize , fsize , date;
};
node a[2000010];
int memo[2000010] , c[2000010] , ha[2000010];
double alpha = 0.75;
int n , m , root , pool , poi , last , ans;
bool cheak(int now){
if((double)a[now].fsize * alpha >= (double)max(a[a[now].ls].fsize , a[a[now].rs].fsize)) return true;
return false;
}
void dfs(int now){
if(!now) return;
dfs(a[now].ls);
if(a[now].f) c[++poi] = now;
else memo[++pool] = now;
dfs(a[now].rs);
}
void build(int l , int r , int &now){
int mid = (l + r) / 2;
now = c[mid];
if(l == r){
a[now].ls = a[now].rs = 0;
a[now].fsize = a[now].tsize = 1;
return;
}
if(l < mid) build(l , mid - 1 , a[now].ls);
else a[now].ls = 0;
build(mid + 1 , r , a[now].rs);
a[now].fsize = a[a[now].ls].fsize + a[a[now].rs].fsize + 1;
a[now].tsize = a[a[now].ls].tsize + a[a[now].rs].tsize + 1;
}
void rebuild(int &now){
poi = 0;
dfs(now);
if(poi) build(1 , poi , now);
else now = 0;
}
void insert(int &now , int t){
if(!now){
now = memo[pool--];
a[now].date = t;
a[now].fsize = a[now].tsize = a[now].f = 1;
a[now].ls = a[now].rs = 0;
return;
}
a[now].fsize++ , a[now].tsize++;
if(a[now].date >= t) insert(a[now].ls , t);
else insert(a[now].rs , t);
if(!cheak(now)) rebuild(now);
}
int ft(int rk){
int now = root;
while(now){
if(a[now].f && a[a[now].ls].fsize + 1 == rk) return a[now].date;
if(a[a[now].ls].fsize + a[now].f >= rk) now = a[now].ls;
else{
rk -= a[a[now].ls].fsize + a[now].f;
now = a[now].rs;
}
}
}
int frk(int t){
int now = root , ans = 1;
while(now){
if(a[now].date >= t) now = a[now].ls;
else{
ans += a[a[now].ls].fsize + a[now].f;
now = a[now].rs;
}
}
return ans;
}
void delet(int &now , int rk){
if(a[now].f && a[a[now].ls].fsize + 1 == rk){
a[now].f = 0;
a[now].fsize--;
return;
}
a[now].fsize--;
if(a[now].f + a[a[now].ls].fsize >= rk) delet(a[now].ls , rk);
else delet(a[now].rs , rk - a[now].f - a[a[now].ls].fsize);
}
void rdelet(int t){
delet(root , frk(t));
if(a[root].tsize * alpha >= a[root].fsize) rebuild(root);
}
int main(){
n = read() , m = read();
for(int i = 1; i <= n; i++) ha[i] = read();
sort(ha + 1 , ha + n + 1); //手动中序遍历
for(int i = 2000000; i >= 1; i--) memo[i] = ++pool;
for(int i = 1; i <= n; i++){
c[i] = i; //模拟dfs操作
a[i].date = ha[i]; //把值放回去
a[i].f = 1; //这个点存在
}
pool -= n; //用了n个内存,内存池里面取n出来
build(1 , n , root); //建树
while(m--){
int opt , x , y;
opt = read() , x = read();
x = last ^ x;
if(opt == 1) insert(root , x);
if(opt == 2) rdelet(x);
if(opt == 3) y = frk(x) , ans = ans ^ y , last = y;
if(opt == 4) y = ft(x) , ans = ans ^ y , last = y;
if(opt == 5) y = ft(frk(x) - 1) , ans = ans ^ y , last = y;
if(opt == 6) y = ft(frk(x + 1)) , ans = ans ^ y , last = y;
}
cout << ans;
return 0;
}
  1. 同学写的,短了很多啊,但是似乎我要快一点,我也不知道为什么,可能是因为直接insert的话,数据专门把树卡成链后,重建次数太多,导致要慢一点,而我直接sort快一些(大雾):
for(register int i = 1; i <= n; i++){
x = read();
insert(root , x);
}

吐槽:这道题数据还是有点水吧,比较未加强数据的直接搬过来能AC,可能是为了卡朝鲜树之类的数据结构吧。

洛谷 P6136 【【模板】普通平衡树(数据加强版)】的更多相关文章

  1. 洛谷 P1120 小木棍 [数据加强版]解题报告

    P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...

  2. 洛谷——P1120 小木棍 [数据加强版]

    P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过5050. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍 ...

  3. 洛谷 P1120 小木棍 [数据加强版]

    P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...

  4. 洛谷 P2241统计方形(数据加强版) 题解

    题目传送门 说是加强版,其实可以把棋盘那道题的代码粘过来(注意要开long long): #include<bits/stdc++.h> using namespace std; ,c; ...

  5. 洛谷—— P1120 小木棍 [数据加强版]

    https://www.luogu.org/problem/show?pid=1120 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接 ...

  6. 洛谷——P2241 统计方形(数据加强版)

    https://www.luogu.org/problem/show?pid=2241 题目背景 1997年普及组第一题 题目描述 有一个n*m方格的棋盘,求其方格包含多少正方形.长方形 输入输出格式 ...

  7. 洛谷.3369.[模板]普通平衡树(Splay)

    题目链接 第一次写(2017.11.7): #include<cstdio> #include<cctype> using namespace std; const int N ...

  8. 洛谷.3369.[模板]普通平衡树(fhq Treap)

    题目链接 第一次(2017.12.24): #include<cstdio> #include<cctype> #include<algorithm> //#def ...

  9. 洛谷.3391.[模板]文艺平衡树(Splay)

    题目链接 //注意建树 #include<cstdio> #include<algorithm> const int N=1e5+5; //using std::swap; i ...

  10. [洛谷P1120]小木棍 [数据加强版]

    题目大意:有一些同样长的木棍,被切割成几段(长$\leqslant$50).给出每段小木棍的长度,找出原始木棍的最小可能长度. 题解:dfs C++ Code: #include<cstdio& ...

随机推荐

  1. (Java实现) 最大团问题 部落卫队

    首先介绍下最大团问题: 问题描述:给一个无向图G=(V,E) ,V是顶点集合,E是边集合.然后在这顶点集合中选取几个顶点,这几 个顶点任意两个之间都有边在E中.求最多可以选取的顶点个数.这几个顶点就构 ...

  2. Java实现 LeetCode 712 两个字符串的最小ASCII删除和(最长公共子串&&ASCII值最小)

    712. 两个字符串的最小ASCII删除和 给定两个字符串s1, s2,找到使两个字符串相等所需删除字符的ASCII值的最小和. 示例 1: 输入: s1 = "sea", s2 ...

  3. 第十届蓝桥杯JavaB组省赛真题

    试题 A: 组队 本题总分:5 分 [问题描述] 作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员, 组成球队的首发阵容. 每位球员担任 1 号位至 5 号位时的评分如下表所示. ...

  4. java实现取球游戏

    /* 今盒子里有 n 个小球,A.B 两人轮流从盒中取球,每个人都可以看到另一个人取了多少个, 也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断. 我们约定: 每个人从盒子中取出的球的 ...

  5. 从linux源码看socket(tcp)的timeout

    从linux源码看socket(tcp)的timeout 前言 网络编程中超时时间是一个重要但又容易被忽略的问题,对其的设置需要仔细斟酌.在经历了数次物理机宕机之后,笔者详细的考察了在网络编程(tcp ...

  6. Promise相关学习

    what? Promise对象表示一个异步操作的最终状态(完成或失败),以及其返回的值 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/ ...

  7. 内存管理,goto的使用,内存的申请和释放,mmap,ioremap

    1.内存管理 (将物理内存映射到内核空间(3G~4G)并使用)  深入内核: 伙伴系统 1.1基本概念    1)linux内核管理内存是以物理内存页为单位       一个物理内存页通常为4KB   ...

  8. SpringBoot设置mysql的ssl连接

    因工作需要,mysql连接需要开启ssl认证,本文主要讲述客户端如何配置ssl连接. 开发环境信息: SpringBoot: 2.0.5.RELEASE mysql-connector-java: 8 ...

  9. Jackson乱码问题

    在配置文件中加入下面的内容 <!-- Json乱码问题配置--> <mvc:annotation-driven> <mvc:message-converters regi ...

  10. navicat 出现 mysql远程连接问题 Lost connection to MySQL server at ‘reading initial communication packet', system error: 0

    今天做服务器上的东西需要看数据库时,突然发现有这个报错,然后自己也查了很多资料 我最后找到一个在my,cnf配置文件中mysqld下加入一条 max_allowed_packet = 500M 也就是 ...