BZOJ 1208 宠物收养所 | 平衡树模板题

BZOJ 1208 宠物收养所

我犯过的错误:删除一个节点后没有update新的根节点,导致size错了!

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
    if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
    x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x){
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}

const int N = 80005, P = 1000000;
int n, flag, root, idx, fa[N], ls[N], rs[N], sze[N], val[N];
ll ans;
#define which(u) (ls[fa[(u)]] == (u))

void debug(){
    printf("root = %d\n", val[root]);
    for(int i = 1; i <= idx; i++)
    printf("val = %d, fa = %d, ls = %d, rs = %d, sze = %d\n", val[i], val[fa[i]], val[ls[i]], val[rs[i]], sze[i]);
}

void upt(int u){
    sze[u] = sze[ls[u]] + sze[rs[u]] + 1;
}
void rotate(int u){
    int v = fa[u], w = fa[v], b = which(u) ? rs[u] : ls[u];
    if(w) which(v) ? ls[w] = u : rs[w] = u;
    which(u) ? (ls[v] = b, rs[u] = v) : (rs[v] = b, ls[u] = v);
    fa[u] = w, fa[v] = u;
    if(b) fa[b] = v;
    upt(v), upt(u);
}
void splay(int u, int tar){
    while(fa[u] != tar){
    if(fa[fa[u]] != tar){
        if(which(u) == which(fa[u])) rotate(fa[u]);
        else rotate(u);
    }
    rotate(u);
    }
    if(!tar) root = u;
}
void insert(int x){
    int u = root, v = 0;
    while(u){
    v = u;
    if(x < val[u]) u = ls[u];
    else u = rs[u];
    }
    fa[++idx] = v, val[idx] = x, sze[idx] = 1;
    if(v) x < val[v] ? ls[v] = idx : rs[v] = idx;
    splay(idx, 0);
}
int find(int x){
    int u = root, v = 0;
    while(u && val[u] != x){
    v = u;
    if(x < val[u]) u = ls[u];
    else u = rs[u];
    }
    return u ? u : v;
}
int getmin(int u){
    while(ls[u]) u = ls[u];
    return u;
}
int getmax(int u){
    while(rs[u]) u = rs[u];
    return u;
}
int getpre(int x){
    int u = find(x);
    splay(u, 0);
    if(val[u] <= x) return u;
    else return getmax(ls[u]);
}
int getnxt(int x){
    int u = find(x);
    splay(u, 0);
    if(val[u] >= x) return u;
    else return getmin(rs[u]);
}
void erase(int u){
    splay(u, 0);
    if(sze[u] == 1) root = 0;
    else if(!ls[u] || !rs[u]) root = ls[u] + rs[u], fa[root] = 0;
    else{
    fa[ls[u]] = 0;
    int v = getmax(ls[u]);
    splay(v, 0);
    rs[v] = rs[u], fa[rs[u]] = v, upt(root);
    }
}

int main(){

    read(n);
    while(n--){
    int op, x;
    read(op), read(x);
    if(!sze[root]){
        insert(x);
        flag = op;
    }
    else if(flag ^ op){
        int u = getpre(x), v = getnxt(x);
        if(u && (!v || x - val[u] <= val[v] - x))
        ans = (ans + (x - val[u]) % P) % P, erase(u);
        else
        ans = (ans + (val[v] - x) % P) % P, erase(v);
    }
    else insert(x);
    }
    write(ans), enter;

    return 0;
}

转载于:https://www.cnblogs.com/RabbitHu/p/BZOJ1208.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值