fhqTreap查不了前驱求助

P6136 【模板】普通平衡树(数据加强版)

S0CRiA @ 2021-08-29 20:15:15

//P6136
#include <bits/stdc++.h>
using namespace std;

inline int read(){
    int s = 0; char ch = getchar();
    while(ch < '0' || ch > '9') ch = getchar();
    while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return s;
}

const int N = 1100010;
struct fhqTreap{
    int ch[N][2], val[N], pri[N], siz[N], tot;
    int root, x, y, z;
    fhqTreap(){
        srand(time(NULL));
        memset(ch, 0, sizeof(ch));
        memset(val, 0, sizeof(val));
        memset(pri, 0, sizeof(pri));
        memset(siz, 0, sizeof(siz));
        tot = root = x = y = z = 0;
        newnode(0xcfcfcfcf), newnode(0x3f3f3f3f);
    }
    void update(int x){ siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1; }
    int newnode(int v){ siz[++tot] = 1, val[tot] = v, pri[tot] = rand(); return tot;}
    int merge(int x, int y){
        if(!x || !y) return x + y;
        if(pri[x] < pri[y]){ ch[x][1] = merge(ch[x][1], y), update(x); return x; }
        else               { ch[y][0] = merge(x, ch[y][0]), update(y); return y; }
    }
    void split(int now, int k, int &x, int &y){
        if(!now){ x = y = 0; return; }
        if(val[now] <= k) x = now, split(ch[now][1], k, ch[now][1], y);
        else              y = now, split(ch[now][0], k, x, ch[now][0]);
        update(now);
    }
    int kth(int now, int k){
        while(true){
            if(k <= siz[ch[now][0]]) now = ch[now][0];
            else if(k == siz[ch[now][0]] + 1) return now;
            else k -= siz[ch[now][0]] + 1, now = ch[now][1];
        }
    }
    void Insert(int k){
        split(root, k, x, y);
        root = merge(merge(x, newnode(k)), y);
    }
    void Delete(int k){
        split(root, k, x, z);
        split(x, k-1, x, y);
        y = merge(ch[y][0], ch[y][1]);
        root = merge(merge(x, y), z);
    }
    int GetRankByVal(int k){
        split(root, k-1, x, y);
        int ans = siz[x] + 1;
        root = merge(x, y);
        return ans;
    }
    int GetValByRank(int k){
        return val[kth(root, k)];
    }
    int GetPre(int k){
        split(root, k-1, x, y);
        int ans = val[kth(x, siz[x])];
        root = merge(x, y);
        return ans;
    }
    int GetNxt(int k){
        split(root, k, x, y);
        int ans = val[kth(y, 1)];
        root = merge(x, y);
        return ans;
    }
} T;

int main(){
    int n, m, last = 0, ans = 0, op, x;
    n = read(), m = read();
    for(int i = 1; i <= n; ++ i) T.val[i] = read();
    for(int i = 1; i <= m; ++ i){
        op = read(), x = read() ^ last;
        switch(op){
            case 1: T.Insert(x); break;
            case 2: T.Delete(x); break;
            case 3: last = T.GetRankByVal(x); break;
            case 4: last = T.GetValByRank(x); break;
            case 5: last = T.GetPre(x); break;
            case 6: last = T.GetNxt(x); break;
        }
        if(op >= 3) ans ^= last;
    }
    printf("%d\n", ans);
    return 0;
}

fhqTreap板子能过P3369


by S0CRiA @ 2021-08-29 20:15:50

一查前驱就卡死


by liubw_ @ 2021-08-29 20:30:59

inline void spl_v(int pos,int key,int &x,int &y){ //按value大小 搜索 
    if(pos==0){
        x=y=0;
        return;
    }
    if(val[pos]<=key) x=pos,spl_v(rson,key,rson,y);
    else y=pos,spl_v(lson,key,x,lson);
    upd(pos);
}
inline void spl_r(int pos,int key,int &x,int &y){ //按子树大小搜索 
    if(pos==0){
        x=y=0;
        return;
    }
    if(siz[lson]<key) x=pos,spl_r(rson,key-siz[lson]-1,rson,y);
    else y=pos,spl_r(lson,key,x,lson);
    upd(pos);
}
inline int pre(int v){ //查询前驱 
    spl_v(root,v-1,x,y);
    spl_r(x,siz[x]-1,x,z);
    r=val[z];
    root=mrg(mrg(x,z),y);
    return r;
}

以上是我平衡树的部分板子

怀疑是你代码里kth()有问题

但我没有证据


by S0CRiA @ 2021-08-29 20:33:52

@16岁 非加强版能过啊


by liubw_ @ 2021-08-29 20:35:57

@Fее_cle6418 话说我的treap还没在洛谷提交过,我自己先去试一下


by liubw_ @ 2021-08-29 21:00:05

@Fее_cle6418 @cymrain07 怀疑是非加强版数据太水了。

这里还是要认为函数有点瑕疵


by liubw_ @ 2021-08-29 21:02:21

by the way 我刚才spl_r函数的if里少了个等号


by liubw_ @ 2021-08-29 21:39:58

匪夷所思的错误,你是不是没有插入初始点


by S0CRiA @ 2021-08-29 21:56:03

@16岁 出来了,读入数组的时候不能用 T.val[i] = read(); ,要 T.Insert(read());


|