题解:无旋Treap练习

版权声明:本文为博主原创文章,欢迎转载并注明来源。 https://blog.csdn.net/w_weilan/article/details/83140859

Tyvj 1728 普通平衡树

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
struct FhqTreap
{
	struct Node
	{
		int ch[2],siz;
		ll key,val;
	};
	vector<Node> v;
	int root;
	FhqTreap():v(1),root(0) {}
	void push_up(int k)
	{
		v[k].siz=v[v[k].ch[0]].siz+v[v[k].ch[1]].siz+1;
	}
	int merge(int a,int b)
	{
		if(!a||!b)return a+b;
		if(v[a].key<v[b].key)
			return v[a].ch[1]=merge(v[a].ch[1],b),push_up(a),a;
		return v[b].ch[0]=merge(a,v[b].ch[0]),push_up(b),b;
	}
	void splitVal(int a,ll w,int &l,int &r)//按值将树划分,使得左子树上的值恰小于w
	{
		if(!a)l=r=0;
		else if(v[a].val>w)splitVal(v[a].ch[0],w,l,v[a].ch[0]),push_up(r=a);
		else splitVal(v[a].ch[1],w,v[a].ch[1],r),push_up(l=a);
	}
	void insert(ll x)
	{
		int a,b;
		v.push_back(Node {{0,0},1,rand(),x});
		splitVal(root,x,a,b),root=merge(merge(a,v.size()-1),b);
	}
	void erase(ll x)
	{
		int a,b,c;
		splitVal(root,x,a,b),splitVal(a,x-1,a,c);
		root=merge(merge(a,merge(v[c].ch[0],v[c].ch[1])),b);
	}
	ll kth(int k)
	{
		for(int u=root,ls;;)
		{
			if(ls=v[v[u].ch[0]].siz,ls+1==k)
				return v[u].val;
			if(ls<k)k-=ls+1,u=v[u].ch[1];
			else u=v[u].ch[0];
		}
	}
	int lower_bound(ll x)
	{
		return upper_bound(x-1);
	}
	int upper_bound(ll x)
	{
		int a,b,ret;
		return splitVal(root,x,a,b),ret=v[a].siz+1,root=merge(a,b),ret;
	}
};
int main()
{
	int n,o,x;
	FhqTreap t;
	for(scanf("%d",&n); n--;)
	{
		scanf("%d%d",&o,&x);
		if(o==1)t.insert(x);
		else if(o==2)t.erase(x);
		else printf("%d\n",o==3?t.lower_bound(x):
			            t.kth(o==4?x:
			                  o==5?t.lower_bound(x)-1:
			                  t.upper_bound(x)));
	}
}

Tyvj 1729 文艺平衡树

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
struct FhqTreap
{
	struct Node
	{
		int ch[2],siz,rev;
		ll key,val;
		void REV()
		{
			rev^=1,swap(ch[0],ch[1]);
		}
	};
	vector<Node> v;
	int root;
	FhqTreap():v(1),root(0) {}
	void push_down(int k)
	{
		if(!k)return;
		for(int i=0,*ch=v[k].ch; i<2; ++i)
			if(ch[i]&&v[k].rev)v[ch[i]].REV();
		v[k].rev=0;
	}
	void push_up(int k)
	{
		if(!k)return;
		v[k].siz=1;
		for(int i=0,*ch=v[k].ch; i<2; ++i)
			if(ch[i])
				v[k].siz+=v[ch[i]].siz;
	}
	int merge(int a,int b)
	{
		if(!a||!b)return a+b;
		if(v[a].key<v[b].key)
			return push_down(a),v[a].ch[1]=merge(v[a].ch[1],b),push_up(a),a;
		return push_down(b),v[b].ch[0]=merge(a,v[b].ch[0]),push_up(b),b;
	}
	void split(int a,int s,int &l,int &r)
	{
		if(!s)l=0,r=a;
		else if(v[v[a].ch[0]].siz<s)
			push_down(a),split(v[a].ch[1],s-v[v[a].ch[0]].siz-1,v[a].ch[1],r),push_up(l=a);
		else
			push_down(a),split(v[a].ch[0],s,l,v[a].ch[0]),push_up(r=a);
	}
	void push_back(ll d)
	{
		v.push_back(Node {{0,0},1,0,rand(),d});
		root=merge(root,v.size()-1);
	}
	void reverse(int l,int r)
	{
		int a,b,c;
		split(root,r,b,c),split(b,l-1,a,b),v[b].REV(),root=merge(merge(a,b),c);
	}
	void print(int u)
	{
		if(!u)return;
		push_down(u);
		print(v[u].ch[0]);
		printf("%d ",v[u].val);
		print(v[u].ch[1]);
	}
};
int main()
{
	int n,m;
	FhqTreap t;
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; ++i)t.push_back(i);
	for(int i=1,l,r; i<=m; ++i)scanf("%d%d",&l,&r),t.reverse(l,r);
	t.print(t.root);
}

序列终结者

说是终结者其实是下面一题的真子集…

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
struct FhqTreap
{
	struct Node
	{
		int ch[2],siz,rev;
		ll key,val,max,add;
		void REV()
		{
			rev^=1,swap(ch[0],ch[1]);
		}
		void ADD(ll v)
		{
			val+=v,max+=v,add+=v;
		}
	};
	vector<Node> v;
	int root;
	FhqTreap():v(1),root(0) {}
	void push_down(int k)
	{
		if(!k)return;
		for(int i=0,*ch=v[k].ch; i<2; ++i)
			if(ch[i])
			{
				v[ch[i]].ADD(v[k].add);
				if(v[k].rev)v[ch[i]].REV();
			}
		v[k].add=v[k].rev=0;
	}
	void push_up(int k)
	{
		if(!k)return;
		v[k].siz=1,v[k].max=v[k].val;
		for(int i=0,*ch=v[k].ch; i<2; ++i)
			if(ch[i])
				v[k].siz+=v[ch[i]].siz,v[k].max=max(v[k].max,v[ch[i]].max);
	}
	int merge(int a,int b)
	{
		if(!a||!b)return a+b;
		if(v[a].key<v[b].key)
			return push_down(a),v[a].ch[1]=merge(v[a].ch[1],b),push_up(a),a;
		return push_down(b),v[b].ch[0]=merge(a,v[b].ch[0]),push_up(b),b;
	}
	void split(int a,int s,int &l,int &r)
	{
		if(!s)l=0,r=a;
		else if(v[v[a].ch[0]].siz<s)
			push_down(a),split(v[a].ch[1],s-v[v[a].ch[0]].siz-1,v[a].ch[1],r),push_up(l=a);
		else
			push_down(a),split(v[a].ch[0],s,l,v[a].ch[0]),push_up(r=a);
	}
	void push_back(ll d)
	{
		v.push_back(Node {{0,0},1,0,rand(),d,d,d});
		root=merge(root,v.size()-1);
	}
	void add(int l,int r,ll d)
	{
		int a,b,c;
		split(root,r,b,c),split(b,l-1,a,b),v[b].ADD(d),root=merge(merge(a,b),c);
	}
	Node ask(int l,int r)
	{
		int a,b,c;
		split(root,r,b,c),split(b,l-1,a,b);
		Node ret=v[b];
		return root=merge(merge(a,b),c),ret;
	}
	void reverse(int l,int r)
	{
		int a,b,c;
		split(root,r,b,c),split(b,l-1,a,b),v[b].REV(),root=merge(merge(a,b),c);
	}
};
int main()
{
	int n,k,l,r;
	FhqTreap t;
	for(scanf("%d",&n); n--;)t.push_back(0);
	for(scanf("%d",&n); n--;)
	{
		scanf("%d%d%d",&k,&l,&r);
		if(k==1)scanf("%d",&k),t.add(l,r,k);
		else if(k==2)t.reverse(l,r);
		else printf("%d\n",t.ask(l,r).max);
	}
}

SuperMemo

比较全面的一个题了,FhqTreap真是好用啊。

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
struct FhqTreap
{
	struct Node
	{
		int ch[2],siz,rev;
		ll key,val,min,add;
		void REV()
		{
			rev^=1,swap(ch[0],ch[1]);
		}
		void ADD(ll v)
		{
			val+=v,min+=v,add+=v;
		}
	};
	vector<Node> v;
	int root;
	FhqTreap():v(1),root(0) {}
	void push_down(int k)
	{
		if(!k)return;
		for(int i=0,*ch=v[k].ch; i<2; ++i)
			if(ch[i])
			{
				v[ch[i]].ADD(v[k].add);
				if(v[k].rev)v[ch[i]].REV();
			}
		v[k].add=v[k].rev=0;
	}
	void push_up(int k)
	{
		if(!k)return;
		v[k].siz=1,v[k].min=v[k].val;
		for(int i=0,*ch=v[k].ch; i<2; ++i)
			if(ch[i])
				v[k].siz+=v[ch[i]].siz,v[k].min=min(v[k].min,v[ch[i]].min);
	}
	int merge(int a,int b)
	{
		if(!a||!b)return a+b;
		if(v[a].key<v[b].key)
			return push_down(a),v[a].ch[1]=merge(v[a].ch[1],b),push_up(a),a;
		return push_down(b),v[b].ch[0]=merge(a,v[b].ch[0]),push_up(b),b;
	}
	void split(int a,int s,int &l,int &r)
	{
		if(!s)l=0,r=a;
		else if(v[v[a].ch[0]].siz<s)
			push_down(a),split(v[a].ch[1],s-v[v[a].ch[0]].siz-1,v[a].ch[1],r),push_up(l=a);
		else
			push_down(a),split(v[a].ch[0],s,l,v[a].ch[0]),push_up(r=a);
	}
	void push_back(ll d)
	{
		v.push_back(Node {{0,0},1,0,rand(),d,d,d});
		root=merge(root,v.size()-1);
	}
	void insert(int x,ll d)
	{
		v.push_back(Node {{0,0},1,0,rand(),d,d,d});
		int a,b,c;
		split(root,x-1,a,b);
		root=merge(merge(a,v.size()-1),b);
	}
	void erase(int x)
	{
		int a,b,c;
		split(root,x,a,b),split(a,x-1,a,c),root=merge(a,b);
	}
	void add(int l,int r,ll d)
	{
		int a,b,c;
		split(root,r,b,c),split(b,l-1,a,b),v[b].ADD(d),root=merge(merge(a,b),c);
	}
	Node ask(int l,int r)
	{
		int a,b,c;
		split(root,r,b,c),split(b,l-1,a,b);
		Node ret=v[b];
		return root=merge(merge(a,b),c),ret;
	}
	void reverse(int l,int r)
	{
		int a,b,c;
		split(root,r,b,c),split(b,l-1,a,b),v[b].REV(),root=merge(merge(a,b),c);
	}
	void revolve(int l,int r,int d)
	{
		int a,b,c,e=r-l+1;
		split(root,r,b,c),split(b,l-1,a,b),split(b,(e-d%e)%e,b,e);
		root=merge(merge(a,merge(e,b)),c);
	}
};
int main()
{
	int n,x,y,d;
	char s[9];
	FhqTreap t;
	for(scanf("%d",&n); n--;)scanf("%d",&d),t.push_back(d);
	for(scanf("%d",&n); n--;)
	{
		scanf("%s%d",s,&x);
		if(s[0]=='A')scanf("%d%d",&y,&d),t.add(x,y,d);
		else if(s[0]=='I')scanf("%d",&d),t.insert(x+1,d);
		else if(s[0]=='D')t.erase(x);
		else if(s[0]=='M')scanf("%d",&y),printf("%d\n",t.ask(x,y).min);
		else if(s[3]=='E')scanf("%d",&y),t.reverse(x,y);
		else scanf("%d%d",&y,&d),t.revolve(x,y,d);
	}
}

猜你喜欢

转载自blog.csdn.net/w_weilan/article/details/83140859
今日推荐