FHQ treap and 文艺平衡树

FHQ treap

概念
分裂

根据某个数 分裂为两棵树

合并

两棵树和为一棵树

/*made in mrd*/
#include <bits/stdc++.h>
using namespace std;
const int N = 2e6 + 10;
#define int long long
#define mem(a, b) memset(a, b, sizeof a)
#define fi first
#define se second
#define pii pair<int, int>
#define pb push_back
int cnt;
struct node {
    int l, r;
    int val, key;
    int size;
} fhq[N];
int root;
int x, y, z;
int newnode(int val) {
    fhq[++cnt].val = val;
    fhq[cnt].key = rand();
    fhq[cnt].size = 1;
    return cnt;
}
void pushup(int now) {
    fhq[now].size = fhq[fhq[now].l].size + fhq[fhq[now].r].size + 1;
}
void split(int now, int val, int &x, int &y) {
    if (!now)
        x = y = 0; 
    else {
        if (fhq[now].val <= val) {
            x = now;
            split(fhq[now].r, val, fhq[now].r, y);
        } else {
            y = now;
            split(fhq[now].l, val, x, fhq[now].l);
        }
        pushup(now);
    }
  
}
int merge(int x, int y) {
    if (!x || !y) return x + y;
    if (fhq[x].key > fhq[y].key) {
        fhq[x].r = merge(fhq[x].r, y);
        pushup(x);
        return x;
    } else {
        fhq[y].l = merge(x, fhq[y].l);
        pushup(y);
        return y;
    }
}
void insert(int val) {
    split(root, val, x, y);
    root = merge(merge(x, newnode(val)), y);
}
void del(int val) {
    split(root, val, x, z);
    split(x, val - 1, x, y);
    y = merge(fhq[y].l, fhq[y].r);
    root = merge(merge(x, y), z);
}
void get_rank(int val) {
    split(root, val - 1, x, y);
    cout<<fhq[x].size + 1<<endl;
    root=merge(x, y);
}
void getsum(int rank) {
    int now = root;
    //cout<<fhq[now].l<<endl;
       //cout<<fhq[fhq[now].l].size<<endl;
    while (now) {
        if (fhq[fhq[now].l].size + 1 == rank) {
            {break;}
        } else if (fhq[fhq[now].l].size >= rank) {
            now = fhq[now].l;
        } else {
            rank -= fhq[fhq[now].l].size+1;
            now = fhq[now].r;
        }
    }
    //cout<<now<<endl;
    cout<< fhq[now].val << endl;
}
void get_pre(int val) {
    split(root, val - 1, x, y);
    int now = x;
    while (fhq[now].r) {
        now = fhq[now].r;
    }
    cout << fhq[now].val << endl;
    root = merge(x, y);
}
void get_nxt(int val) {
    split(root, val, x, y);
    int now = y;
    while (fhq[now].l) {
        now = fhq[now].l;
    }
    cout << fhq[now].val << endl;
    root = merge(x, y);
}
signed main() {
    int n;
    cin >> n;
    while (n--) {

        //cout<<rand( )<<endl;
        int a, b, c;
        cin >> a >> b;
        if (a == 1) {
            insert(b);
        } else if (a == 2) {
            del(b);
        } else if (a == 3) {
             get_rank(b);
        } else if (a == 4) {
            getsum(b) ;
        } else if (a == 5) {
            get_pre(b) ;
        } else
             get_nxt(b) ;
    }
    return 0;
}

文艺平衡树

概念
分裂

根据size大小分裂成两个树

合并

根据随机值合并

懒标记

pushdown 往下传

代码

/*made in mrd*/
#include <bits/stdc++.h>
using namespace std;
const int N = 2e6 + 10;
#define int long long
#define mem(a, b) memset(a, b, sizeof a)
#define fi first
#define se second
#define pii pair<int, int>
#define pb push_back
int cnt;
struct node {
    int l, r;
    int val, key;
    int size;
    bool flag;
} fhq[N];
int root;
int x, y, z;
int newnode(int val) {
    fhq[++cnt].val = val;
    fhq[cnt].key = rand();  
    fhq[cnt].size = 1;
    return cnt;
}
void pushdown(int now)
{
    swap(fhq[now].l,fhq[now].r);
    fhq[fhq[now].l].flag^=1;
    fhq[fhq[now].r].flag^=1;
    fhq[now].flag^=1;
}
void pushup(int now) {
    fhq[now].size = fhq[fhq[now].l].size + fhq[fhq[now].r].size + 1;
}
void split(int now, int size, int &x, int &y) {
    if (!now)
        x = y = 0; 
    else {
        if(fhq[now].flag) pushdown(now);
        if (fhq[fhq[now].l].size < size) {
            x = now;
            split(fhq[now].r, size-fhq[fhq[now].l].size-1, fhq[now].r, y);
        } else {
            y = now;
            split(fhq[now].l, size, x, fhq[now].l);
        }
        pushup(now);
    }
  
}
int merge(int x, int y) {
    if (!x || !y) return x + y;
    if (fhq[x].key < fhq[y].key) {
        if(fhq[x].flag) pushdown(x);
        fhq[x].r = merge(fhq[x].r, y);
        pushup(x);
        return x;
    } else {
        if(fhq[y].flag) pushdown(y);
        fhq[y].l = merge(x, fhq[y].l);
        pushup(y);
        return y;
    }
}
void reverse(int l,int r)
{
    
    split(root,l-1,x,y);
    split(y ,r-l+1,y,z);
    fhq[y].flag^=1;
    root=merge(merge(x,y),z);
}
void output(int now)
{
     if(!now) return ;
     if(fhq[now].flag) pushdown(now);
     output(fhq[now].l);
     cout<<fhq[now].val<<" ";
     output(fhq[now].r); 
}
signed main() {
    int n,m;
    cin >> n>>m;
   for(int i=1;i<=n;i++)
   {
      root=merge(root,newnode(i));
   }
   
   while(m--)
   {
       int l,r;
       cin>>l>>r;
       reverse(l,r);
   }
   output(root);
    return 0;
}

上一篇:P3369 【模板】普通平衡树 例题 各种算法的比较


下一篇:多对多关系数据库表 java描述