救命啊,出人命了!

P3391 【模板】文艺平衡树

SammyChu @ 2019-10-01 18:33:34

我要被Fhq_Treap折磨致死了,求各位好心人救我。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
const int N=1e5;
inline void read(int &x)
{
    int w=x=0;
    char ch=getchar();
    while(ch<'0'||'9'<ch)
        w|=(ch=='-'),ch=getchar();
    while('0'<=ch&&ch<='9')
        x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
    x=w?-x:x;
}
int n,m,num[N|1],a,b;
int root,tot,L,R;
struct Treap
{
    int val,siz;
    bool rev;
    int lc,rc,rnd;
}tr[N|1];
#define lid tr[id].lc
#define rid tr[id].rc
void upon(int id)
{
    tr[id].siz=tr[lid].siz+tr[rid].siz+1;
}
int New(int x)
{
    tr[++tot].rnd=rand();
    tr[tot].val=x,tr[tot].siz=1;
    return tot;
}
int top,stk[N|1];
void build(int x)
{ 
    for(int i=1,id,now,ch;i<=x;++i)
    {
        id=New(num[i]),now=stk[top],ch=0;
        while(top&&tr[id].rnd<=tr[now].rnd)
            ch=stk[top],now=stk[--top];
        lid=ch,upon(id);
        if(top)
            tr[now].rc=id,upon(now);        
        else
            root=id;
        stk[++top]=id;
    }
}
void deal(int id)
{
    tr[id].rev^=1,swap(lid,rid);
}
void down(int id)
{
    if(!tr[id].rev)
        return;
    deal(lid),deal(rid);
    tr[id].rev=0;
}
void split(int id,int x,int &l,int &r)
{
    if(!id)
        l=r=0;
    else
    {
        down(id);
        int y=x-tr[lid].siz-1;
        if(y>=0)
            l=id,split(rid,y,rid,r);
        else
            r=id,split(lid,x,l,lid);
        upon(id);
    }
}
int merge(int l,int r) 
{
    if(!l||!r)
        return l+r;
    int id=tr[l].rnd<=tr[r].rnd?l:r;
    down(id);
    if(id==l)
        rid=merge(rid,r),upon(id);
    else
        lid=merge(l,lid),upon(id);
    return id;
}
void reverse(int x,int y)
{
    int id;
    split(root,y,L,R),split(L,x-1,L,id);
    deal(id),root=merge(merge(L,id),R);
}
void print(int id)
{
    down(id);
    if(lid)
        print(lid);
    printf("%d ",tr[id].val);
    if(rid)
        print(rid);
}
int main()
{
    srand(time(0));
    read(n),read(m);
    for(int i=1;i<=n;++i)
        num[i]=i;
    build(n);
    while(m--)
        read(a),read(b),reverse(a,b);
    print(root);
    return 0;
}

by _Album_ @ 2019-10-01 18:45:12

加三目运算符


by _Album_ @ 2019-10-01 18:47:05

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<deque>
#include<queue>
#include<stack>
#include<algorithm>
#include<iomanip>
#include<cstdlib>
#include<vector>
#include<cmath>

#define ll long long
#define N 1000010
#define I inline

using namespace std;

struct Treap{
    int cnt , root;
    #define lson(x) node[x].l
    #define rson(x) node[x].r

    struct Node{
        int dis;
        int rd;
        int size;
        int l , r;
        Node(int dis = 0) : dis(dis) , rd(rand()) , size(1) , l(0) , r(0){}
    }node[N];

    I void update(int x){
        node[x].size = (lson(x) ? node[lson(x)].size : 0) + (rson(x) ? node[rson(x)].size : 0) + 1;     //这些三目运算符不加会出错
    }

    void split(int n , int k , int &x , int &y){
        if(!n) x = y = 0;
        else if(node[n].dis >= k){
            split(lson(n) , k , x , y);
            lson(n) = y;
            update(y = n);
        }
        else {
            split(rson(n) , k , x , y);
            rson(n) = x;
            update(x = n);
        }
    }

    int merge(int x , int y){
        if(!x || !y){
            return x + y;
        }
        if(node[x].rd < node[y].rd){
            rson(x) = merge(rson(x) , y);
            update(x);
            return x;
        }
        else{
            lson(y) = merge(x , lson(y));
            update(y);
            return y;
        }
    }

    I void insert(int k){
        int x , y;
        split(root , k , x , y);
        node[++ cnt] = Node(k);
        root = merge(merge(x , cnt) , y);
    }

    I void remove(int k){
        int x , y , z;
        split(root , k , x , y);
        split(y , k + 1 , y , z);
        y = merge(lson(y) , rson(y));
        root = merge(merge(x , y) , z);
    }

    I int rank(int k){
        int x , y , ans;
        split(root , k , x , y);
        ans = (x ? node[x].size : 0) + 1;
        root = merge(x , y);
        return ans;
    }

    int search(int n , int r){
        int rank = (lson(n) ? node[lson(n)].size : 0) + 1;          //还有这里
        if(r == rank) return node[n].dis;
        else if(r < rank) return search(lson(n) , r);
        else return search(rson(n) , r - rank);
    }

    inline int lower(int k) {
        int x, y, t;
        split(root, k, x, y);
        t = x;
        while (rson(t)) t = rson(t);
        root = merge(x, y);
        return node[t].dis;
    }

    inline int upper(int k) {
        int x, y, t;
        split(root, k + 1, x, y);
        t = y;
        while (lson(t)) t = lson(t);
        root = merge(x, y);
        return node[t].dis;
    }
}treap;

int main(){
    int n , opt , x;
    scanf("%d"  , &n);
    for(int i = 1; i <= n; i ++){
        scanf("%d%d" , &opt , &x);
        switch(opt){
            case 1 :
                treap.insert(x);
                break;
            case 2 :
                treap.remove(x);
                break;
            case 3 :
                printf("%d\n" , treap.rank(x));
                break;
            case 4 :
                printf("%d\n" , treap.search(treap.root , x));
                break;
            case 5 : 
                printf("%d\n" , treap.lower(x));
                break;
            case 6 : 
                printf("%d\n" , treap.upper(x));
                break;
        }
    }
    return 0;
}

by SammyChu @ 2019-10-01 19:26:05

@Payphone—X 多谢


by SammyChu @ 2019-10-01 19:27:15

不过好像还是错的……


by Zofia @ 2019-10-02 09:24:55

不要再学用处不大的知识点!

不要再学用处不大的知识点!

不要再学用处不大的知识点!


by 千瑞 @ 2019-11-25 18:16:09

多了一个人


by Richard21477 @ 2020-07-17 09:53:00

split写错了

void split(int loc,int sze,int &x,int &y){
    if (loc==0){
        x=y=0;
        return;
    }
    down(loc);
    if (all[all[loc].l].s>=sze){
        y=loc;
        split(all[loc].l,sze,x,all[loc].l);
    }
    else{
        x=loc;
        split(all[loc].r,sze,all[loc].r,y);
    }
    update(loc);
}

(不保证我是对的)


by Richard21477 @ 2020-07-17 10:16:07

倒数第四行改一下,sze-all[all[loc].l].s-1


|