fhq treap

#include<bits/stdc++.h>
using namespace std;
int n,m,tot;
struct treap
{
	int ch[3],pri,size,v;
}t[100010];
void update(int x)
{
	t[x].size=1+t[t[x].ch[0]].size+t[t[x].ch[1]].size; 
}
int new_node(int x)
{
	t[++tot].v=x;
	t[tot].size=1;
	t[tot].pri=rand();
	return tot;
}
int merge(int x,int y)
{
	if(!x||!y) return x+y;
	if(t[x].pri<t[y].pri)
	{
		t[x].ch[1]=merge(t[x].ch[1],y);
		update(x);
		return x;
	}
	else 
	{
		t[y].ch[0]=merge(x,t[y].ch[0]);
		update(y);
		return y;
	}
}
void split(int x,int k,int &a,int &b)
{
	if(!x) a=b=0;
	else
	{
		if(t[x].v<=k) 
		{
			a=x;
			split(t[x].ch[1],k,t[x].ch[1],b);
		}
		else
		{
			b=x;
			split(t[x].ch[0],k,a,t[x].ch[0]);
		}
		update(x);
	}
}
int kth(int x,int k)
{
	while(1)
	{
		if(k<=t[t[x].ch[0]].size)
		{
			x=t[x].ch[0];
		}
		else if(k==t[t[x].ch[0]].size+1) return x;
		else k-=t[t[x].ch[0]].size+1,x=t[x].ch[1];
	}
}
int main()
{
	srand(time(NULL));
	scanf("%d",&n);
	int root=0;
	while(n--)
	{
		int c,a,x,y,z;
		scanf("%d%d",&c,&a);
		if(c==1)
		{
			split(root,a,x,y);
			root=merge(merge(x,new_node(a)),y);
		}
		if(c==2)
		{
			split(root,a,x,z);
			split(x,a-1,x,y);
			y=merge(t[y].ch[0],t[y].ch[1]);
			root=merge(merge(x,y),z);
		}
		if(c==3)
		{
			split(root,a-1,x,y);
			printf("%d\n",t[x].size+1);
			root=merge(x,y);
		}
		if(c==4)
		{
			printf("%d\n",t[kth(root,a)].v);
		}
		if(c==5)
		{
			split(root,a-1,x,y);
			printf("%d\n",t[kth(x,t[x].size)].v);
			root=merge(x,y);
		}
		if(c==6)
		{
			split(root,a,x,y);
			printf("%d\n",t[kth(y,1)].v);
			root=merge(x,y);
		}
	}
	return 0;
}


```cpp
#include<bits/stdc++.h>
#define ll long long
#define db double
#define file(a) freopen(#a".in", "r", stdin), freopen(#a".out", "w", stdout)
#define sky fflush(stdout)
#define gc getchar
#define pc putchar
namespace IO{
	template<class T>
	inline void read(T &s){
		s = 0;char ch = gc();bool f = 0;
		while(ch < '0' || '9'<ch) {if(ch == '-') f = 1; ch = gc();}
		while('0'<=ch && ch<='9') {s = s * 10 + (ch ^ 48); ch = gc();}
		if(ch == '.'){
			T p = 0.1;ch = gc();
			while('0' <= ch && ch <= '9') {s = s + p * (ch ^ 48);p /= 10;ch = gc();}
		}
		s = f ? -s : s;
	}
	template<class T,class ...A>
	inline void read(T &s,A &...a){
		read(s); read(a...);
	}
	template<class T>
	inline void print(T x){
		if(x<0) {x = -x; pc('-');}
		static char st[40];
		static int top;
		top = 0;
		do{st[++top] = x - x / 10 * 10 + '0';} while(x /= 10);
		while(top) {pc(st[top--]);}
	}
	template<class T,class ...A>
	inline void print(T s,A ...a){
		print(s); print(a...);
	}
};
using IO::read;
using IO::print;
const int N = 2e5;
std::mt19937 rd(time(0) + clock() );
struct Treap{
	#define lc(x) t[x].ch[0]
	#define rc(x) t[x].ch[1]
	int rt[N + 3];
	int tot;
	struct node{
		int pri;
		ll val;
		int ch[2], sz;
		bool rev;
		ll sum;
	}t[N * 80 + 3];
	inline int newnode(ll val){
		t[++tot].pri = rd();
		t[tot].val = val;
		t[tot].sz = 1;
		t[tot].ch[0] = t[tot].ch[1] = 0;
		t[tot].rev = 0;
		t[tot].sum = val;
		return tot;
	}
	inline int clone(int x){
		int y = newnode(0);
		t[y] = t[x];
		return y;
	}
	inline void change_rev(int &x){
		x = clone(x);
		t[x].rev ^= 1;
		std::swap(lc(x), rc(x) );
	}
	inline void pushdown(int x){
		if(t[x].rev){
			if(lc(x) ) change_rev(lc(x) );
			if(rc(x) ) change_rev(rc(x) );
			t[x].rev = 0;
		}
	}
	inline void pushup(int x){
		t[x].sz = t[lc(x)].sz + t[rc(x)].sz + 1;
		t[x].sum = t[lc(x)].sum + t[rc(x)].sum + t[x].val;
	}
 	std::pair<int, int> split(int x, int k){
		if(!x) return std::make_pair(0, 0);
		x = clone(x);
		pushdown(x);
		if(t[lc(x)].sz + 1 <= k){
			auto tmp = split(rc(x), k - t[lc(x)].sz - 1);
			rc(x) = tmp.first;
			pushup(x);
			return std::make_pair(x, tmp.second);
		}else{
			auto tmp = split(lc(x), k);
			lc(x) = tmp.second;
			pushup(x);
			return std::make_pair(tmp.first, x);
		}
	}
	inline void ins(int id, int nd, int p, ll k){
		auto tmp = split(rt[id], p);
		rt[nd] = merge(merge(tmp.first, newnode(k) ), tmp.second);
	}
	inline void del(int id, int nd, int p){
		auto tmp1 = split(rt[id], p);
		auto tmp2 = split(tmp1.first, p - 1);
		tmp2.second = merge(lc(tmp2.second), rc(tmp2.second) );
		rt[nd] = merge(merge(tmp2.first, tmp2.second), tmp1.second);
	}
	int merge(int x, int y){
		if(!x || !y) return x | y; 
		pushdown(x); pushdown(y);
		if(t[x].pri < t[y].pri){
			rc(x) = merge(rc(x), y);
			pushup(x);
			return x;
		}else{
			lc(y) = merge(x, lc(y) );
			pushup(y);
			return y;
		}
	}
	inline void reverse(int id, int nd, int l, int r){
		auto tmp = split(rt[id], l - 1);
		auto tmp2 = split(tmp.second, r - l + 1);
		change_rev(tmp2.first);
		rt[nd] = merge(tmp.first, merge(tmp2.first, tmp2.second) );
	}
	inline ll query_sum(int id, int nd, int l, int r){
		auto tmp = split(rt[id], l - 1);
		auto tmp2 = split(tmp.second, r - l + 1);
		ll ans = t[tmp2.first].sum;
		rt[nd] = merge(tmp.first, merge(tmp2.first, tmp2.second) );
		return ans;
	}
	#undef lc
	#undef rc
}t;
int main(){
	//file(a);
	int Q; read(Q);
	ll la = 0;
	for(int i = 1; i <= Q; ++i){
		int x, op; read(x, op);
		if(op == 1){
			ll p, k; read(p, k);
			p ^= la; k ^= la;
			t.ins(x, i, p, k);
		}
		if(op == 2){
			ll p; read(p);
			p ^= la;
			t.del(x, i, p);
		}	
		if(op == 3){
			ll l, r; read(l, r);
			l ^= la; r ^= la;
			t.reverse(x, i, l, r);
		}
		if(op == 4){
			ll l, r; read(l, r);
			l ^= la; r ^= la;
			printf("%lld\n", la = t.query_sum(x, i, l, r) );
		}
	}
	return 0;
}
#include<bits/stdc++.h>
#define ll long long
#define db double
#define file(a) freopen(#a".in", "r", stdin), freopen(#a".out", "w", stdout)
#define sky fflush(stdout)
#define gc getchar
#define pc putchar
namespace IO{
	template<class T>
	inline void read(T &s){
		s = 0;char ch = gc();bool f = 0;
		while(ch < '0' || '9'<ch) {if(ch == '-') f = 1; ch = gc();}
		while('0'<=ch && ch<='9') {s = s * 10 + (ch ^ 48); ch = gc();}
		if(ch == '.'){
			T p = 0.1;ch = gc();
			while('0' <= ch && ch <= '9') {s = s + p * (ch ^ 48);p /= 10;ch = gc();}
		}
		s = f ? -s : s;
	}
	template<class T,class ...A>
	inline void read(T &s,A &...a){
		read(s); read(a...);
	}
	template<class T>
	inline void print(T x){
		if(x<0) {x = -x; pc('-');}
		static char st[40];
		static int top;
		top = 0;
		do{st[++top] = x - x / 10 * 10 + '0';} while(x /= 10);
		while(top) {pc(st[top--]);}
	}
	template<class T,class ...A>
	inline void print(T s,A ...a){
		print(s); print(a...);
	}
};
using IO::read;
using IO::print;
const int N = 5e5;
std::mt19937 rd(time(0) + clock() );
struct Treap{
	#define lc(x) t[x].ch[0]
	#define rc(x) t[x].ch[1]
	int rt[N + 3];
	int tot;
	struct node{
		int pri, val;
		int ch[2], sz, cnt;
	}t[N * 50 + 3];
	inline int newnode(int val, int ti = 1){
		t[++tot].pri = rd();
		t[tot].val = val;
		t[tot].sz = ti;
		t[tot].cnt = ti;
		t[tot].ch[0] = t[tot].ch[1] = 0;
		return tot;
	}
	inline void pushup(int x){
		t[x].sz = t[lc(x)].sz + t[rc(x)].sz + t[x].cnt;
	}
 	std::pair<int, int> split(int x, int k){
		if(!x) return std::make_pair(0, 0);
		int y = newnode(0);
		t[y] = t[x];
		if(t[y].val <= k){
			auto tmp = split(rc(y), k);
			rc(y) = tmp.first;
			pushup(y);
			return std::make_pair(y, tmp.second);
		}else{
			auto tmp = split(lc(y), k);
			lc(y) = tmp.second;
			pushup(y);
			return std::make_pair(tmp.first, y);
		}
	}
	int merge(int x, int y){
		if(!x || !y) return x | y; 
		if(t[x].pri < t[y].pri){
			rc(x) = merge(rc(x), y);
			pushup(x);
			return x;
		}else{
			lc(y) = merge(x, lc(y) );
			pushup(y);
			return y;
		}
	}
	inline void ins(int id, int nd, int k, int ti = 1){
		auto tmp = split(rt[id], k);
		auto lt = split(tmp.first, k - 1);
		if(lt.second){
			t[lt.second].cnt += ti;
			pushup(lt.second);
			rt[nd] = merge(merge(lt.first, lt.second), tmp.second);
		}else{
			rt[nd] = merge(merge(lt.first, newnode(k, ti) ), tmp.second);
		}
	}
	inline void del(int id, int nd, int k, int ti = 1){
		auto tmp1 = split(rt[id], k);
		auto tmp2 = split(tmp1.first, k - 1);
		if(t[tmp2.second].cnt - ti <= 0){
			tmp2.second = merge(lc(tmp2.second), rc(tmp2.second) );
		}else{
			t[tmp2.second].cnt -= ti;
			pushup(tmp2.second);
		}
		rt[nd] = merge(merge(tmp2.first, tmp2.second), tmp1.second);
	}
	inline int rank(int id, int nd, int k){
		auto tmp = split(rt[id], k - 1);
		int ans = t[tmp.first].sz + 1;
		rt[nd] = merge(tmp.first, tmp.second);
		return ans;
	}
	inline int kth(int x, int k){
		while(true){
			if(k <= t[lc(x)].sz){
				x = lc(x);
			}else if(k <= t[lc(x)].sz + t[x].cnt){
				return t[x].val;
			}else{
				k -= t[lc(x)].sz + t[x].cnt;
				x = rc(x);
			}
		}
	}
	inline int pre(int id, int nd, int k){
		auto tmp = split(rt[id], k - 1);
		int ans = kth(tmp.first, t[tmp.first].sz);
		rt[nd] = merge(tmp.first, tmp.second);
		return ans;
	}
	inline int nxt(int id, int nd, int k){
		auto tmp = split(rt[id], k);
		int ans = kth(tmp.second, 1);
		rt[nd] = merge(tmp.first, tmp.second);
		return ans;
	}
	void dfs(int x){
		if(lc(x) ) dfs(lc(x) );
		fprintf(stderr, "%d ", t[x].val);
		if(rc(x) ) dfs(rc(x) );
	}
}t;
int main(){
	//file(a);
	int Q; read(Q);
	t.ins(0, 0, INT_MAX);
	t.ins(0, 0, -INT_MAX);
	/*
	t.dfs(t.rt[0]);
	fprintf(stderr, "\n");
	*/
	for(int i = 1; i <= Q; ++i){
		int x, op, k; read(x, op, k);
		if(op == 1){
			t.ins(x, i, k);
		}
		if(op == 2){
			t.del(x, i, k);
		}
		if(op == 3){
			printf("%d\n", t.rank(x, i, k) - 1);
		}
		if(op == 4){
			printf("%d\n", t.kth(t.rt[x], k + 1) );
			t.rt[i] = t.rt[x];
		}
		if(op == 5){
			printf("%d\n", t.pre(x, i, k) );
		}
		if(op == 6){
			printf("%d\n", t.nxt(x, i, k) );
		}
		/*
		t.dfs(t.rt[i]);
		fprintf(stderr, "\n");
		*/
	}
	return 0;
}
posted @   cbdsopa  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示