扶苏的问题

题目链接

  • 利用Splay进行序列操作时,将数组坐标整体平移1,给0留出空间,并在操作过程中始终保持0号节点的特性
  • 用#define语句和struct的构造函数简化编程复杂度
  • 对名字空间(namespace)有了更深刻的理解
  • Splay的常数较大,难以通过1e6规模的数据
  • 在建树时,根据Splay的特性,直接建出一条只有右儿子的链即可,时间复杂度仍然是正确的。
点击查看代码
#include <bits/stdc++.h>
#define l(x) ch[x][0]
#define r(x) ch[x][1] 
using namespace std;
struct t1
{
	long long va,maxn;
	long long add;
	int change;
	t1()
	{
		va=maxn=LLONG_MIN;
		add=0;
		change=INT_MAX;
	}
}t[1000005];
int fa[1000005],ch[1000005][2];
void pushdown(int x)
{
	if(t[x].change!=INT_MAX)
	{
		if(l(x))
		{
			t[l(x)].va=t[x].change;
			t[l(x)].maxn=t[x].change;
			t[l(x)].change=t[x].change;
			t[l(x)].add=0;
		}
		if(r(x))
		{
			t[r(x)].va=t[x].change;
			t[r(x)].maxn=t[x].change;
			t[r(x)].change=t[x].change;
			t[r(x)].add=0;
		}
		t[x].change=INT_MAX;
	}
	if(t[x].add)
	{
		if(l(x))
		{
			t[l(x)].va+=t[x].add;
			t[l(x)].maxn+=t[x].add;
			t[l(x)].add+=t[x].add;
		}
		if(r(x))
		{
			t[r(x)].va+=t[x].add;
			t[r(x)].maxn+=t[x].add;
			t[r(x)].add+=t[x].add;
		}
		t[x].add=0;
	}
}
int get(int x)
{
	return ch[fa[x]][1]==x;
}
void maintain(int x)
{
	t[x].maxn=max(t[x].va,max(t[l(x)].maxn,t[r(x)].maxn));
}
void rotate(int x)
{
	int y=fa[x],z=fa[y],opt=get(x);
	ch[y][opt]=ch[x][opt^1];
	if(ch[x][opt^1])
	{
		fa[ch[x][opt^1]]=y;
	}
	fa[y]=x;
	ch[x][opt^1]=y;
	fa[x]=z;
	if(z)
	{
		ch[z][y==ch[z][1]]=x;
	}
	maintain(y);
	maintain(x);
}
void update(int x,int k)
{
	if(fa[x]!=k)
	{
		update(fa[x],k);
	}
	pushdown(x);
}
void Splay(int x,int k)
{
	update(x,k);
	while(fa[x]!=k)
	{
		int y=fa[x],z=fa[y];
		if(z==k)
		{
			rotate(x);
			break;
		}
		if(get(x)==get(y))
		{
			rotate(y);
			rotate(x);
		}
		else
		{
			rotate(x);
			rotate(x);
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n,q;
	cin>>n>>q;
	ch[1][1]=2;
	for(int i=2;i<=n+1;i++)
	{
		cin>>t[i].va;
		ch[i][1]=i+1;
		fa[i]=i-1;
	}
	fa[n+2]=n+1;
	t[n+1].maxn=t[n+1].va;
	for(int i=n;i>=2;i--)
	{
		t[i].maxn=max(t[i+1].maxn,t[i].va);
	}
	for(int i=1;i<=q;i++)
	{
		int opt,l,r,x;
		cin>>opt>>l>>r;
		Splay(l,0);
		Splay(r+2,l);
		int id=ch[r+2][0];
		if(opt==1)
		{
			cin>>x;
			pushdown(id);
			t[id].change=x;
			t[id].va=t[id].maxn=x;
		}
		else if(opt==2)
		{
			cin>>x;
			pushdown(id);
			t[id].add=x;
			t[id].va+=x;
			t[id].maxn+=x;
		}
		else
		{
			cout<<t[id].maxn<<"\n";
		}
	}
	return 0;
}
posted @ 2024-10-04 16:28  D06  阅读(5)  评论(0编辑  收藏  举报