p2234求助+玄关
  • 板块灌水区
  • 楼主zhouwenbo1234
  • 当前回复0
  • 已保存回复0
  • 发布时间2025/2/6 11:49
  • 上次更新2025/2/6 15:06:23
查看原帖
p2234求助+玄关
1331638
zhouwenbo1234楼主2025/2/6 11:49

Splay没过样例求调

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=4e6+5,INF=1e9+5;

int n,a,ans;
bool mark[N],markk[N];
struct node{
	int s[2],f,w;
	int size;
	void init(int _w,int _f)
	{
		w=_w;
		f=_f;
		size=1;
	}
}tree[N];

int read()
{
	int x=0,f=1;
	char c=getchar();
	while (c<'0'||c>'9')
	{
		if (c=='-')
			f=-1;
		c=getchar();
	}
	while (c>='0'&&c<='9')
	{
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}

void push_up(int x)
{
	tree[x].size=tree[tree[x].s[0]].size+tree[tree[x].s[1]].size+1;
}

int root,idx;
void rotate(int x)
{
	int y=tree[x].f;
	int z=tree[y].f;
	int k=tree[y].s[1]==x;
	tree[z].s[tree[z].s[1]==y]=x;
	tree[x].f=z;
	tree[y].s[k]=tree[x].s[k^1];
	tree[tree[x].s[k^1]].f=y;
	tree[x].s[k^1]=y;
	tree[y].f=x;
	push_up(y);
	push_up(x);
}

void splay(int x,int k)
{
	while (tree[x].f!=k)
	{
		int y=tree[x].f;
		int z=tree[y].f;
		if (z!=k)
		{
			if ((tree[y].s[1]==x)^(tree[z].s[1]==y))
				rotate(x);
			else
				rotate(y);
		}
		rotate(x);
	}
	if (!k)
		root=x;
}

void insert(int x)
{
	int u=root;
	int f=0;
	while(u&&tree[u].w!=x)
	{
		f=u;
		u=tree[u].s[x>tree[u].w];
	}
	u=++idx;
	if (f)
		tree[f].s[x>tree[f].w]=u;
	tree[u].init(x,f);
	splay(u,0);
}

void find(int x)
{
	int u=root;
	if (!u)
		return ;
	while(tree[u].s[x>tree[u].w]&&x!=tree[u].w)
		u=tree[u].s[x>tree[u].w];
	splay(u,0);
}

int get_next(int x,int f)
{
	find(x);
	int u=root;
	if (tree[u].w>x&&f)
		return u;
	if (tree[u].w<x&&!f)
		return u;
	u=tree[u].s[f];
	while(tree[u].s[f^1])
		u=tree[u].s[f^1];
	return u;
}

signed main()
{
	n=read();
	a=read();
	insert(INF),insert(-INF);
	if (a>=0)
		mark[a]=1;
	else if (a<0)
		markk[-a]=1;
	insert(a);
	ans=a;
	for (int i=2;i<=n;i++)
	{
		a=read();
		if (a>=0&&mark[a])
			continue;
		else{
			mark[a]=1;
			insert(a);
		}
		if (a<0&&markk[-a])
			continue;
		else{
			markk[-a]=1;
			insert(a);
		}
		int q=tree[get_next(a,0)].w;
		int h=tree[get_next(a,1)].w;
		ans+=min(labs(q-a),labs(h-a));
	}
	cout <<ans<<endl;
	return 0;
}

蒟蒻用Splay求前驱以及后继,用特判过相减得0。并且已知多半是get_next出错。

2025/2/6 11:49
加载中...