社区讨论

Treap求助

P1486[NOI2004] 郁闷的出纳员参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lo836jaf
此快照首次捕获于
2023/10/27 12:01
2 年前
此快照最后确认于
2023/10/27 12:01
2 年前
查看原帖
已经完全不会写了呢
CPP
#include <bits/stdc++.h>
using std::pair;
using std::make_pair;

int num, min, tag, sum;

struct node {
    int lc, rc;
    int val, pri, siz;
} d[400005];
int cnt;

void resize(int n) {
    d[n].siz = d[d[n].lc].siz + d[d[n].rc].siz + 1;
    return;
}

int root;
std::mt19937 rnd(0);

pair<int, int> split(int n, int k) {
    if(!n)
        return make_pair(0, 0);

    pair<int, int> p;
    if(d[n].val > k) {
        p = split(d[n].lc, k);
        d[n].lc = p.second;
        p.second = n;
    } else {
        p = split(d[n].rc, k);
        d[n].rc = p.first;
        p.first = n;
    }
    resize(n);

    return p;
}

int merge(int a, int b) {
    if(!a || !b)
        return a + b;
    
    if(d[a].pri < d[b].pri) {
        d[a].rc = merge(d[a].rc, b);
        resize(a);
        return a;
    } else {
        d[b].lc = merge(a, d[b].lc);
        resize(b);
        return b;
    }
}

void insert(int k) {
    ++ cnt;
    d[cnt].val = k;
    d[cnt].pri = rnd();
    d[cnt].siz = 1;

    pair<int, int> p = split(root, k);
    p.first = merge(p.first, cnt);
    root = merge(p.first, p.second);

    return;
}

void del(void) {
    pair<int, int> p = split(root, min - tag - 1);
    sum += d[p.first].siz;
    root = p.second;

    return;
}

int query(int k) {
    int t = root;
    while(true) {
        if(d[d[t].rc].siz == k - 1)
            return d[t].val + tag;
        
        if(d[d[t].rc].siz >= k)
            t = d[t].rc;
        else
            t = d[t].lc,
            k = k - d[d[t].rc].siz - 1;
    }

    return 0;
}

int main(void) {
    char s[15];
    int k;
    scanf("%d%d", &num, &min);

    while(num --) {
        scanf("%s%d", s, &k);
        switch(s[0]) {
            case 'I':
                if(k < min)
                    break;
                insert(k - tag);
                break;

            case 'A':
                tag += k;
                break;
            
            case 'S':
                tag -= k;
                del();
                break;
            
            case 'F':
                if(d[root].siz < k)
                    puts("-1");
                else {
                    k = query(k);
                    printf("%d\n", k);
                }
                break;

            default:
                break;
        }
    }

    printf("%d", sum);

    return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...