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