FHQ为啥超时两个 求调QAQ
查看原帖
FHQ为啥超时两个 求调QAQ
1381324
wuyuhui楼主2024/12/14 14:48
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 300001;
int head = 0;
int cnt = 0;
int key[MAXN];
int ls[MAXN];
int rs[MAXN];
int size[MAXN];
double priority[MAXN];
int limit;
int enter=0;
int change=0;

//没有词频压缩  所以出现次数就是1
void up(int i) {
    size[i] = size[ls[i]] + size[rs[i]] + 1;
}

void split(int l, int r, int i, int num) {
    if (i == 0) {
        rs[l] = ls[r] = 0;
    } else {
        if (key[i] <= num) {
            rs[l] = i;
            split(i, r, rs[i], num);
        } else {
            ls[r] = i;
            split(l, i, ls[i], num);
        }
        up(i);
    }
}

int merge(int l, int r) {
    if (l == 0 || r == 0) {
        return l + r;
    }
    if (priority[l] >= priority[r]) {
        rs[l] = merge(rs[l], r);
        up(l);
        return l;
    } else {
        ls[r] = merge(l, ls[r]);
        up(r);
        return r;
    }
}

//没有词频压缩  直接就是新增节点
void add(int num) {
    split(0, 0, head, num);
    key[++cnt] = num;
    size[cnt] = 1;
    priority[cnt] = (double)rand() / RAND_MAX;
    head = merge(merge(rs[0], cnt), ls[0]);
}

//删除节点的时候 是将树按照num分裂  然后将<=num 的按照 num-1 分裂
//将那么 >num-1 的树头结点一定是num  只要将这个节点忽略就是删除节点
void remove(int num) {
    split(0, 0, head, num);
    int lm = rs[0];
    int r = ls[0];
    split(0, 0, lm, num - 1);
    int l = rs[0];
    int m = ls[0];
    head = merge(merge(l, merge(ls[m], rs[m])), r);
}

int index(int i, int x) {
    if (size[ls[i]] >= x) {
        return index(ls[i], x);
    } else if (size[ls[i]] + 1 < x) {
        return index(rs[i], x - size[ls[i]] - 1);
    } else {
        return key[i];
    }
}

int index(int x) {
    return index(head, x);
}

void departure(){
    int num=limit-change-1;
    split(0,0,head,num);
    int r;
    r=ls[0];
    head=r;
    up(head);

}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    srand(time(0));
    int n;
    cin >> n>>limit;
    for(int i=1;i<=n;i++){
        char op;
        int x;
        cin>>op>>x;
        if(op=='I'){
            if(x>=limit){
                add(x-change);
                enter++;
            }
        }
        else if(op=='A'){
            change+=x;
        }
        else if(op=='S'){
            change-=x;
            departure();
        }
        else{
            if(x>size[head]){
                cout<<-1<<endl;
            }
            else{
                cout << index(size[head] - x + 1) + change << endl;
            }
        }
    }
    cout<<enter-size[head]<<endl;
    return 0;
}
20 0
I 4
F 1

I 6
S 9
F 14

I 6
I 7
A 8
I 3
F 2


I 9
I 6
I 6
S 3
S 5
I 6
F 1

I 3
A 2
F 5

有没有大佬可以帮忙看看FHQ Treap为什么会超时 #1 #3

2024/12/14 14:48
加载中...