权值线段树较大数据点WA
查看原帖
权值线段树较大数据点WA
1048327
KANO07楼主2024/5/16 10:05

wa了9到12,感觉大小都开够了,写的也挺对(

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
const ll N = 1e5+5;
const ll M = 1e7+5;
struct node{
    ll l,r,id;
    ll sum;
}tree[N<<6];
ll cnt;
void insert(ll& p, ll l,ll r,ll x, ll k){
    if(!p) p = ++cnt;
    if(l == r){
        tree[p].sum += k;
        return;
    }
    ll mid = (l + r)/2;
    if(x <= mid) insert(tree[p].l,l,mid,x,k);
    else insert(tree[p].r,mid+1,r,x,k);
    tree[p].sum += k;
}

bool flag = 0;
ll get_rank(ll p, ll l, ll r, ll x){
    if(l == r){
        if(tree[p].sum == 0) flag = 1; //这个数不存在
        return 1;
    }
    ll mid = (l + r)/2;
    if(x <= mid) return get_rank(tree[p].l,l,mid,x);
    else return tree[tree[p].l].sum + get_rank(tree[p].r,mid+1,r,x);
}

ll kth(ll p, ll l, ll r, ll k){
    if(l == r) return l;
    ll mid = (l + r)/2;
    ll left_sum = tree[tree[p].l].sum;
    if(k <= left_sum) return kth(tree[p].l,l,mid,k);
    else return kth(tree[p].r,mid+1,r,k-left_sum);
}

ll get_pre(ll p, ll l, ll r, ll x){
    ll index = get_rank(p, l, r, x);
    return kth(p, l, r, index-1);
}

ll get_nex(ll p, ll l, ll r, ll x){
    flag = 0;
    ll index = get_rank(p, l, r, x);
    if(!flag) index++; //这个数存在的话,返回他的下一个数
    return kth(p, l, r, index);
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    tree[0].id = ++cnt;
    ll n;
    cin>>n;
    while(n--){
        ll opt,x;
        cin>>opt>>x;
        switch(opt){
            case 1: insert(tree[0].id,1,2*M,x + M, 1); break;
            case 2: insert(tree[0].id,1,2*M,x + M, -1); break;
            case 3: cout<<get_rank(tree[0].id,1,2*M,x+M)<<endl; break;
            case 4: cout<<kth(tree[0].id,1,2*M,x) - M<<endl; break;
            case 5: cout<<get_pre(tree[0].id,1,2*M,x+M) - M<<endl; break;
            case 6: cout<<get_nex(tree[0].id,1,2*M,x+M) - M<<endl; break;
        }
    }
    return 0;
}
2024/5/16 10:05
加载中...