ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

FHQ treap and 文艺平衡树

2021-11-02 13:05:05  阅读:184  来源: 互联网

标签:val merge int fhq 文艺 treap now FHQ size


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;
}

标签:val,merge,int,fhq,文艺,treap,now,FHQ,size
来源: https://www.cnblogs.com/mrd-T/p/15498362.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有