123789456ye

已AFO

平衡树专题题解

A 普通平衡树

题意:Luogu
题解:没有
code

B [NOI2005]维修数列

名字好鬼啊
这里

C [TJOI2013]最长上升子序列

题意:Luogu
题解:设\(dp[i]\)表示以\(i\)结尾的最长上升子序列长度,\(pos[i]\)表示\(i\)节点对应下标,\(val[i]\)表示以\(i\)节点为根的区间的LIS长度

\[val[rt]=max(max(val[ls],val[rs]),dp[pos[rt]) \]

然后就没了
code

D [HNOI2002]营业额统计

题意:Luogu
题解:直接查前驱后继即可。注意要插两个哨兵。
code

E [HNOI2004]宠物收养场

题意:Luogu
题解:建两棵树,一颗宠物一颗人,然后就没了查一下前驱后继,优先前驱
code

F 文艺平衡树

题意:Luogu
题解:没有
话说fhq和线段树挺像的来着
code

G [TJOI2019]甲苯先生的滚榜

诡异的标题
TJOI2019D1T2就是这种水题?
题意:Luogu
题解:就是一个板子(然而我把\(x,y\)封装在里面之后一直WA,设成全局变量就过了???我tm调了两三个小时啊)
另外这题很卡常,读优和输优都要写上
然而我本地还是过不了
然而luogu机子真快啊
code

A code

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
#define ls son[rt][0]
#define rs son[rt][1]
int rnd[maxn],val[maxn],son[maxn][2],siz[maxn];
int tot,root,x,y,z;
inline void read(int& x)
{
	x=0;char c=getchar();int f=1;
	while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	x*=f;
}
inline void update(int rt)
{
	siz[rt]=siz[ls]+siz[rs]+1;
}
void split(int rt,int v,int& x,int& y)
{
	if(!rt) x=y=0;
	else
	{
		if(val[rt]<=v)
		{
			x=rt;
			split(rs,v,rs,y);
		}
		else
		{
			y=rt;
			split(ls,v,x,ls);
		}
		update(rt);
	}
	
}
int merge(int x,int y)
{
	if(!x||!y) return x|y;
	if(rnd[x]<=rnd[y])
	{
		son[x][1]=merge(son[x][1],y);
		update(x);
		return x;
	}
	else
	{
		son[y][0]=merge(x,son[y][0]);
		update(y);
		return y;
	}
}
inline int newnode(int v)
{
	siz[++tot]=1;
	val[tot]=v;
	rnd[tot]=rand();
	return tot;
}
inline void insert(int v)
{
	split(root,v,x,y);
	root=merge(merge(x,newnode(v)),y);
}
inline void pop(int v)
{
	split(root,v,x,z);
	split(x,v-1,x,y);
	y=merge(son[y][0],son[y][1]);
	root=merge(merge(x,y),z);
}
inline int getrank(int v)
{
	split(root,v-1,x,y);
	int ans=siz[x]+1;
	root=merge(x,y);
	return ans;
}
inline int getkth(int rt,int k)
{
	while(true)
	{
		if(k<=siz[ls]) rt=ls;
		else if(k==siz[ls]+1) return rt;
		else k-=siz[ls]+1,rt=rs;
	}
}
inline int lower(int v)
{
	split(root,v-1,x,y);
	int ans=val[getkth(x,siz[x])];
	merge(x,y);
	return ans;
}
inline int upper(int v)
{
	split(root,v,x,y);
	int ans=val[getkth(y,1)];
	merge(x,y);
	return ans;
}
int main()
{
	srand((unsigned long long)new char);
	int n,op,v;
	read(n);
	for(int i=1;i<=n;++i)
	{
		read(op),read(v);
		if(op==1) insert(v);
		else if(op==2) pop(v);
		else if(op==3) printf("%d\n",getrank(v));
		else if(op==4) printf("%d\n",val[getkth(root,v)]);
		else if(op==5) printf("%d\n",lower(v));
		else printf("%d\n",upper(v));
	}
	return 0;
}

back to top

C code

#include<bits/stdc++.h>
using namespace std;
inline void read(int& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
namespace fhqTreap
{
	#define maxn 100005
	#define ls son[rt][0]
	#define rs son[rt][1]
	int root,tot,x,y;
	int son[maxn][2],siz[maxn],maxval[maxn],val[maxn],rnd[maxn],dp[maxn],pos[maxn];
	inline void pushup(const int& rt)
	{
		siz[rt]=siz[ls]+siz[rs]+1;
		val[rt]=max(max(val[ls],val[rs]),dp[pos[rt]]);
	}
	void split_val(int rt,int v,int& x,int& y)
	{
		if(!rt) x=y=0;
		else
		{
			if(v>=val[rt]) x=rt,split_val(rs,v,rs,y);
			else y=rt,split_val(ls,v,x,ls);
			pushup(rt);
		}
	}
	void split_size(int rt,int k,int& x,int& y)
	{
		if(!rt) x=y=0;
		else
		{
			if(k>siz[ls]) x=rt,split_size(rs,k-siz[ls]-1,rs,y);
			else y=rt,split_size(ls,k,x,ls);
			pushup(rt);
		}
	}
	int merge(int x,int y)
	{
		if(!x||!y) return x|y;
		if(rnd[x]<rnd[y])
		{
			son[x][1]=merge(son[x][1],y);
			pushup(x);
			return x;
		}
		else
		{
			son[y][0]=merge(x,son[y][0]);
			pushup(y);
			return y;
		}
	}
	inline int newnode(const int& v,const int& posi)
	{
		siz[++tot]=1,rnd[tot]=rand();
		pos[tot]=posi,dp[pos[tot]]=val[tot]=v;
		return tot;
	}
	void print(int rt)
	{
		if(ls) print(ls);
		printf("%d ",val[rt]);
		if(rs) print(rs);
	}
}
using namespace fhqTreap;
int dp[maxn];
int main()
{
	srand(time(NULL));
	int n,pos;
	read(n);
	for(int i=1;i<=n;++i)
	{
		read(pos);
		split_size(root,pos,x,y);
		root=merge(merge(x,newnode(val[x]+1,i)),y);
		printf("%d\n",val[root]);
	}
	return 0;
}

back to top

D code

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
#define inf 0x3f3f3f3f
#define ls son[rt][0]
#define rs son[rt][1]
inline void read(int& x)
{
	x=0;char c=getchar();int f=1;
	while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	x*=f;
}
inline int min(int x,int y)
{
	return x<y?x:y;
}
int rnd[maxn],siz[maxn],val[maxn],son[maxn][2],tot,root;
int x,y,z;
inline void update(int rt)
{
	siz[rt]=siz[ls]+siz[rs]+1;
}
void split(int rt,int k,int& x,int& y)
{
	if(!rt) 
	{
		x=y=0;
		return;
	}
	if(val[rt]<=k) x=rt,split(rs,k,rs,y);
	else y=rt,split(ls,k,x,ls);
	update(rt);
}
int merge(int x,int y)
{
	if(!x||!y) return x|y;
	if(rnd[x]<rnd[y])
	{
		son[x][1]=merge(son[x][1],y);
		update(x);
		return x;
	}
	else
	{
		son[y][0]=merge(x,son[y][0]);
		update(y);
		return y;
	}
}
inline int newnode(int v)
{
	siz[++tot]=1;
	val[tot]=v;
	rnd[tot]=rand();
	return tot;
}
inline void insert(int v)
{
	split(root,v,x,y);
	root=merge(merge(x,newnode(v)),y);
}
inline int getkth(int rt,int k)
{
	while(true)
	{
		if(k<=siz[ls]) rt=ls;
		else if(k==siz[ls]+1) return rt;
		else k-=siz[ls]+1,rt=rs;
	}
}
inline int lower(int v)
{
	split(root,v,x,y);
	int ans=val[getkth(x,siz[x])];
	root=merge(x,y);
	return ans;
}
inline int upper(int v)
{
	split(root,v,x,y);
	int ans=val[getkth(y,1)];
	root=merge(x,y);
	return ans;
}
inline bool find(int v)
{
	return lower(v)==v;
}
int main()
{
	srand(time(NULL));
	int n,v,ans=0;
	read(n);
	insert(inf),insert(-inf);
	for(int i=1;i<=n;++i)
	{
		read(v);
		if(find(v)) continue;
		int pre=lower(v),las=upper(v);
		if(pre==-inf&&las==inf) ans+=v;
		else if(pre==-inf) ans+=las-v;
		else if(las==inf) ans+=v-pre;
		else ans+=min(v-pre,las-v);
		insert(v);
	}
	printf("%d\n",ans);
	return 0;
}

back to top

E code

#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
#define P 1000000
#define inf 0x3f3f3f3f
#define ls son[rt][0]
#define rs son[rt][1]
inline void read(int& x)
{
	x=0;char c=getchar();int f=1;
	while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	x*=f;
}
inline int min(int x,int y)
{
	return x<y?x:y;
}
struct fhqtreap
{
	int rnd[maxn],siz[maxn],val[maxn],son[maxn][2],tot,root;
	int x,y,z;
	inline void update(int rt)
		{
			siz[rt]=siz[ls]+siz[rs]+1;
		}
	void split(int rt,int k,int& x,int& y)
		{
			if(!rt) 
			{
				x=y=0;
				return;
			}
			if(val[rt]<=k) x=rt,split(rs,k,rs,y);
			else y=rt,split(ls,k,x,ls);
			update(rt);
		}
	int merge(int x,int y)
		{
			if(!x||!y) return x|y;
			if(rnd[x]<rnd[y])
			{
				son[x][1]=merge(son[x][1],y);
				update(x);
				return x;
			}
			else
			{
				son[y][0]=merge(x,son[y][0]);
				update(y);
				return y;
			}
		}
	inline void pop(int v)
		{
			split(root,v,x,z);
			split(x,v-1,x,y);
			y=merge(son[y][0],son[y][1]);
			root=merge(merge(x,y),z);
		}
	inline int newnode(int v)
		{
			siz[++tot]=1;
			val[tot]=v;
			rnd[tot]=rand();
			return tot;
		}
	inline void insert(int v)
		{
			split(root,v,x,y);
			root=merge(merge(x,newnode(v)),y);
		}
	inline int getkth(int rt,int k)
		{
			while(true)
			{
				if(k<=siz[ls]) rt=ls;
				else if(k==siz[ls]+1) return rt;
				else k-=siz[ls]+1,rt=rs;
			}
		}
	inline int getrank(int v)
		{
			split(root,v-1,x,y);
			int ans=siz[x]+1;
			root=merge(x,y);
			return ans;
		}
	inline int lower(int v)
		{
			split(root,v-1,x,y);
			int ans=val[getkth(x,siz[x])];
			root=merge(x,y);
			return ans;
		}
	inline int upper(int v)
		{
			split(root,v,x,y);
			int ans=val[getkth(y,1)];
			root=merge(x,y);
			return ans;
		}
	inline bool find(int v)
		{
			return lower(v)==v;
		}
	inline bool empty()
		{
			return getrank(inf)==2;
		}
}st[2];
inline int solve(int v,int op)
{
	if(st[op^1].empty())
	{
		st[op].insert(v);
		return 0;
	}
	int pre=st[op^1].lower(v),las=st[op^1].upper(v);
	if(pre==-inf)
	{
		st[op^1].pop(las);
		return las-v;
	}
	else if(las==inf)
	{
		st[op^1].pop(pre);
		return v-pre;
	}
	else
	{
		if(las+pre<v+v)
		{
			st[op^1].pop(las);
			return las-v;
		}
		else
		{
			st[op^1].pop(pre);
			return v-pre;
		}
	}
}
int main()
{
	srand(time(NULL));
	int n,op,v;
	long long ans=0;
	read(n);
	st[0].insert(inf),st[0].insert(-inf);
	st[1].insert(inf),st[1].insert(-inf);
	for(int i=1;i<=n;++i)
	{
		read(op),read(v);
		ans+=solve(v,op);
	}
	printf("%lld\n",ans%P);
	return 0;
}

back to top

F code

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
#define ls son[rt][0]
#define rs son[rt][1]
int rnd[maxn],val[maxn],son[maxn][2],siz[maxn],lazy[maxn];
int tot,root,x,y,z;
inline void read(int& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
inline void update(int rt)
{
	siz[rt]=siz[ls]+siz[rs]+1;
}
inline void pushdown(int rt)
{
	if(!lazy[rt]) return;
	swap(ls,rs);
	lazy[ls]^=1,lazy[rs]^=1;
	lazy[rt]=0;
}
void split(int rt,int k,int& x,int& y)
{
	if(!rt) x=y=0;
	else
	{
		pushdown(rt);
		if(k>siz[ls]) x=rt,split(rs,k-siz[ls]-1,rs,y);
		else y=rt,split(ls,k,x,ls);
		update(rt);
	}
}
int merge(int x,int y)
{
	if(!x||!y) return x|y;
	if(rnd[x]<=rnd[y])
	{
		pushdown(x);
		son[x][1]=merge(son[x][1],y);
		update(x);
		return x;
	}
	else
	{
		pushdown(y);
		son[y][0]=merge(x,son[y][0]);
		update(y);
		return y;
	}
}
inline int newnode(int v)
{
	siz[++tot]=1;
	val[tot]=v;
	rnd[tot]=rand();
	return tot;
}
inline void insert(int v)
{
	split(root,v,x,y);
	root=merge(merge(x,newnode(v)),y);
}
void print(int rt)
{
	pushdown(rt);
	if(ls) print(ls);
	printf("%d ",val[rt]);
	if(rs) print(rs);
}
int main()
{
	srand((unsigned long long)new char);
	int n,m,fr,to;
	read(n);read(m);
	for(int i=1;i<=n;++i) insert(i);
	for(int i=1;i<=m;++i)
	{
		read(fr),read(to);
		split(root,to,x,z);
		split(x,fr-1,x,y);
		lazy[y]^=1;
		root=merge(merge(x,y),z);
	}
	print(root);
	return 0;
}

back to top

G code

#include<bits/stdc++.h>
using namespace std;
#define ui unsigned int
#define rg register 
#define maxn 100005
ui last,n,m,seed;
int root,tot,x,y,z;
int num[maxn*10],tim[maxn*10];
inline ui randnum()
{
	seed=seed*17+last;
	return seed%m+1;
}
struct Person
{
	int num,tim;
};
template<typename T>
struct fhqTreap
{
#define ls son[rt][0]
#define rs son[rt][1]
	T val[maxn];
	int son[maxn][2],rnd[maxn],siz[maxn];
	inline void update(rg int rt)
		{
			siz[rt]=siz[ls]+siz[rs]+1;
		}
	void split(rg int rt,rg T v,rg int& x,rg int& y)
		{
			if(!rt) x=y=0;
			else
			{
				if(val[rt].num<v.num||(val[rt].num==v.num&&val[rt].tim>=v.tim))
					y=rt,split(ls,v,x,ls);
				else x=rt,split(rs,v,rs,y);
				update(rt);
			}
		}
	void split(rg int rt,rg int k,rg int& x,rg int& y)
		{
			if(!rt) x=y=0;
			else
			{
				if(k<=siz[ls]) y=rt,split(ls,k,x,ls);
				else x=rt,split(rs,k-siz[ls]-1,rs,y);
				update(rt);
			}
		}
	int merge(rg int x,rg int y)
		{
			if(!x||!y) return x|y;
			if(rnd[x]<rnd[y])
			{
				son[x][1]=merge(son[x][1],y);
				update(x);
				return x;
			}
			else
			{
				son[y][0]=merge(x,son[y][0]);
				update(y);
				return y;
			}
		}
	inline int newnode(rg T v)
		{
			val[++tot]=v;
			rnd[tot]=rand();
			siz[tot]=1;
			return tot;
		}
	inline int getrank(rg T v)
		{
			split(root,v,x,y);
			int ans=siz[x];
			root=merge(x,y);
			return ans;
		}
	#undef ls
	#undef rs
};
fhqTreap<Person> st;
inline void write(rg int x)
{
	if(x>=10) write(x/10);
	putchar(x%10+'0');
}
int main()
{
	//freopen("roll.in","r",stdin),freopen("roll.out","w",stdout);
	int T;
	scanf("%d",&T);
	last=7;
	while(T--)
	{
		scanf("%d%d%d",&m,&n,&seed);
		root=tot=0;
		memset(num,0,sizeof(num));
		memset(tim,0,sizeof(tim));
		memset(st.son,0,sizeof(st.son));
		rg unsigned int ta,tb;
		for(rg int i=1;i<=n;++i)
		{
 			ta=randnum(),tb=randnum();
			if(!num[ta])
			{
				++num[ta],tim[ta]+=tb;
				rg int now=st.newnode((Person){num[ta],tim[ta]});
				st.split(root,(Person){num[ta],tim[ta]},x,y);
				root=st.merge(st.merge(x,now),y);
			}
			else
			{
				st.split(root,(Person){num[ta],tim[ta]},x,y);
				st.split(y,1,y,z);
				++st.val[y].num,st.val[y].tim+=tb;
				++num[ta],tim[ta]+=tb;
				root=st.merge(x,z);
				st.split(root,st.val[y],x,z);
				root=st.merge(st.merge(x,y),z);
			}
			write(last=st.getrank((Person){num[ta],tim[ta]}));
			puts(" ");
		}
	}
	return 0;
}

back to top

posted @ 2020-01-15 09:09  123789456ye  阅读(188)  评论(0编辑  收藏  举报