首页 > 其他 > 详细

loj10145. 「一本通 4.6 练习 2」郁闷的出纳员

时间:2018-08-15 20:54:53      阅读:166      评论:0      收藏:0      [点我收藏+]

思路:

  简单的treap+模拟。

  但这道题的题面有误导群众的嫌疑,因为题中并没有明确刚进入公司就离开的算不算在离开公司的人中。

  当然,对于这道题的数据,题目意思是不算在内。

 

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<string>
using namespace std;
const int maxn = 80010;
inline void qread(int &x) {
    x = 0;
    register int ch = getchar(), flag = 0;
    while(ch < 0 || ch > 9)        {
        if(ch == -)    flag = 1;
        ch = getchar();
    }
    while(ch >= 0 && ch <= 9)    x = 10 * x + ch - 48, ch = getchar();
    if(flag)    x = -x;
}
int rt = 0, tpn, v[maxn], l[maxn], r[maxn], R[maxn], sz[maxn], vn[maxn];
inline void update(int x) {
    sz[x] = sz[l[x]] + sz[r[x]] + vn[x];
}
inline void zig(int &x) {
    int t = l[x];
    l[x] = r[t];
    r[t] = x;
    update(x);
    update(t);
    x = t;
}
inline void zag(int &x) {
    int t = r[x];
    r[x] = l[t];
    l[t] = x;
    update(x);
    update(t);
    x = t;
}
void insert(int &x, int w) {
    if(!x)    {
        x = ++tpn;
        v[x] = w;
        R[x] = rand();
        sz[x] = vn[x] = 1;
        return ;
    }
    if(w < v[x])    insert(l[x], w);
    else if(w > v[x])    insert(r[x], w);
    else            vn[x]++;
    update(x);
    if(l[x] && R[l[x]] < R[x])    zig(x);
    if(r[x] && R[r[x]] < R[x])    zag(x);
}
void pop(int &x, int w) {
    if(w < v[x])    pop(l[x], w);
    else if(w > v[x])    pop(r[x], w);
    else {
        if(vn[x] > 1)    vn[x]--;
        else if(!l[x] || !r[x])    x = l[x] | r[x];
        else if(R[l[x]] < R[r[x]])    zig(x), pop(x, w);
        else                        zag(x), pop(x, w);
    }
    update(x);
}
int ask(int x, int w){
    if(!x)        return -1;
    if(w < v[x])    return ask(l[x], w);
    if(w > v[x])    return ask(r[x], w);
    return     x;
}
int findr(int x, int w){
    int res = 0;
    while(x){
        if(v[x] == w)    return res + sz[l[x]] + 1;
        if(v[x] > w)    x = l[x];
        else            res += sz[l[x]] + vn[x], x = r[x];
    }
    return res;
}
int findk(int x, int k){
    if(k >= sz[l[x]] + 1 && k <= sz[l[x]] + vn[x])    return v[x];
    if(k <= sz[l[x]])    return findk(l[x], k);
    return     findk(r[x], k - sz[l[x]] - vn[x]);
}
int findpre(int x, int w){
    int res = -0x3f3f3f3f;
    while(x){
        if(w <= v[x])    x = l[x];
        else            res = v[x], x = r[x];
    }
    return res;
}
int findnxt(int x, int w){
    int res = 0x3f3f3f3f;
    while(x){
        if(w < v[x])    res = v[x], x = l[x];
        else            x = r[x];
    }
    return res;
}
int main(void) {
    srand(11535);
    int n, minn, nminn, ans = 0;
    qread(n);
    qread(minn);
    nminn = minn;
    while(n--){
        string op;
        int k;
        cin >> op;
        qread(k);
        if(op == "I"){
            if(k >= minn)
                insert(rt, k - minn + nminn);        
        }
        else if(op == "A")
            nminn -= k;
        else if(op == "S"){
            nminn += k;
            int t;
            while((t = findpre(rt, nminn)) != -0x3f3f3f3f) 
                pop(rt, t), ans++;
        }
        else
            printf("%d\n", k > sz[rt] ? -1 : findk(rt, sz[rt] - k + 1) + minn - nminn);
    }
    printf("%d\n", ans);
}

 

loj10145. 「一本通 4.6 练习 2」郁闷的出纳员

原文:https://www.cnblogs.com/junk-yao-blog/p/9483899.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!