fhq 平衡樹

P3369 【模板】普通平衡樹(按照val值分裂)

#include<bits/stdc++.h>
#define random(x) ((rand() % x))
#define endl '\n'
using namespace std;
const int maxn = 1e6 + 10;
int m, sz;
int size[maxn], ls[maxn], rs[maxn], val[maxn], key[maxn];
inline void pushup(int rt){size[rt] = size[ls[rt]] + size[rs[rt]] + 1;	}
inline int add(int k){
	size[++sz] = 1;
	val[sz] = k;
	key[sz] = rand();
	return sz;	
}
inline void split(int rt, int k, int & x, int & y){
	if(!rt){
		x = y = 0;
		return;
	}
	if(val[rt] <= k){
		x = rt;
		split(rs[rt], k, rs[rt], y);
	}
	else{
		y = rt;
		split(ls[rt], k, x, ls[rt]);
	}
	pushup(rt);
}
inline int hebin(int x, int y){
	if(!x || !y) return x + y;
	if(key[x] < key[y]){
		rs[x] = hebin(rs[x], y);
		pushup(x);
		return x;
	}
	else{
		ls[y] = hebin(x, ls[y]);
		pushup(y);
		return y;
	}
}
inline int Kth(int root, int k){
	while(1){
		if(k <= size[ls[root]]) root = ls[root];
		else if(k == size[ls[root]] + 1) return root;
		else{ k -= (size[ls[root]] + 1); root = rs[root];}
	}
}
int main()
{
	int op, num;
	srand((unsigned int)time(0));
	scanf("%d", &m);
	int root = 0, x, y, z;
	while(m --){
		scanf("%d %d", &op, &num);
		if(op == 1){
			split(root, num, x, y);
			root = hebin(hebin(x, add(num)), y);
		}
		else if(op == 2){
			split(root, num, x, z);
			split(x, num-1, x, y);
			y = hebin(ls[y], rs[y]);
			root = hebin(hebin(x, y), z);
		}
		else if(op == 3){
			split(root, num-1, x, y);
			cout << size[x] + 1 << endl;
			root = hebin(x, y);
		}
		else if(op == 4){
			cout << val[Kth(root, num)] << endl;
		}
		else if(op == 5){
			split(root, num-1, x, y);
			cout << val[Kth(x, size[x])] << endl;
			root = hebin(x, y);
		}
		else if(op == 6){
			split(root, num, x, y);
			cout << val[Kth(y, 1)] << endl;
			root = hebin(x, y);
		}
	}
	return 0;
}

P3391 【模板】文藝平衡樹(Splay)(按照size分裂)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<map>
#include<string>
#include<vector>
#include<set>
#include<bitset>
#include<algorithm>
#include<ctime>
using namespace std;
#define ll long long
#define lb long double
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
#define clr(a, b) memset(a, b, sizeof(a))
#define lowbit(x) x & -x
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define PB push_back
#define POP pop_back
#define max_ll 9223372036854775807
#define PII pair<int, int>
#define random(x) (rand()%x)
//srand((ll)time(0));
//freopen("E://one.txt","r",stdin); //輸入重定向,輸入數據將從in.txt文件中讀取
//freopen("E://oneout.txt","w",stdout); //輸出重定向,輸出數據將保存在out.txt文件中
//std::ios::sync_with_stdio(false);
const double eps = 1e-14;
const double pi = acos(-1);
const int maxn = 2e5 + 10;//30000000
const int maxm = (maxn << 5);
const ll mod = 1e9 + 7;
const int hash_mod = 19260817;
int n, m, sz;
int lazy[maxn], ls[maxn], rs[maxn], siz[maxn], val[maxn], key[maxn];
void pushdown(int rt){
    if(lazy[rt]){
        swap(ls[rt], rs[rt]);
        lazy[ls[rt]] ^= 1; lazy[rs[rt]] ^= 1;
        lazy[rt] = 0;
    }
}
void pushup(int rt){siz[rt] = siz[ls[rt]] + siz[rs[rt]] + 1;}
int add(int k){
    siz[++sz] = 1;
    val[sz] = k;
    key[sz] = rand();
    return sz;
}
void split(int rt, int k, int & x, int & y){
    if(!rt){
        x = y = 0;
        return;
    }
    pushdown(rt);
    if(siz[ls[rt]] + 1 <= k){
        x = rt;
        split(rs[rt], k - siz[ls[rt]] - 1, rs[rt], y);
    }
    else{
        y = rt;
        split(ls[rt], k, x, ls[rt]);
    }
    pushup(rt);
}
int hebin(int x, int y){
    if(!x || !y) return x + y;
    if(key[x] < key[y]){
        pushdown(x);
        rs[x] = hebin(rs[x], y);
        pushup(x);
        return x;
    }
    else{
        pushdown(y);
        ls[y] = hebin(x, ls[y]);
        pushup(y);
        return y;
    }
}
void print(int root){
    pushdown(root);
    if(ls[root]) print(ls[root]);
    cout << val[root] << ' ';
    if(rs[root]) print(rs[root]);
}
int main(){
    int l, r;
    srand((int)time(0));
    scanf("%d %d", &n, &m);
    int root = 0, x, y, z;
    for(int i = 1 ; i <= n ; ++ i) root = hebin(root, add(i));
    for(int i = 1 ; i <= m ; ++ i){
        scanf("%d %d", &l, &r);
        split(root, r, x, z);
        split(x, l - 1, x, y);
        lazy[y] ^= 1;
        root = hebin(hebin(x, y), z);
    }
    print(root);
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章