ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P2286宠物收养所(Splay)

2021-12-07 15:01:53  阅读:251  来源: 互联网

标签:ch cur int 宠物 Splay fa ff root P2286


传送门:宠物收养所
可以考虑只维护一棵 Splay,随时判断宠物和领养者谁多,把多的插入到 Splay 里,类似营业额统计,对于新加进来的少的求前驱后继并比较谁更近。(注意判断相等的特殊情况,处理按题面来)
然后累计到答案里就可以啦。(reliese 操作删除的是某个值而不是节点编号,只有我这个蒟蒻才会错啦)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 80000 + 10;
const int mod = 1000000;
int n,res,tot,root;
int pet,cus;
int opt[N],spe[N],val[N],fa[N],siz[N],cnt[N],ch[N][2];
int create(int v,int fs)
{
	val[++tot] = v,fa[tot] = fs;
	ch[tot][0] = ch[tot][1] = 0;
	siz[tot] = cnt[tot] = 1;
	return tot;
}
void maintain(int x)
{
	if(not x) return;
	siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + cnt[x];
}
int getwhich(int x)
{
	return x == ch[fa[x]][1];
}
void rotate(int x)
{
	int ff = fa[x],gf = fa[ff];
	int k = getwhich(x),tmp = ch[x][k^1];
	fa[tmp] = ff,ch[ff][k] = tmp;
	fa[x] = gf;
	if(gf) ch[gf][getwhich(ff)] = x;
	fa[ff] = x,ch[x][k^1] = ff;
	maintain(x),maintain(ff);
}
void splay(int x)
{
	for(int ff = fa[x];ff = fa[x];rotate(x)) 
	    if(fa[ff]) rotate(getwhich(ff) == getwhich(x) ? ff : x);
	root = x;
}
void ins(int v)
{
	if(not root)
	{
		root = create(v,0);
		return ;
	}
	int cur = root,ff = 0;
	while(1)
	{
		if(val[cur] == v)
		{
			cnt[cur]++;
			maintain(cur),maintain(ff);
			splay(cur); break;
		}
		ff = cur;
		cur = ch[cur][val[cur] < v];
		if(not cur)
		{
			ch[ff][val[ff] < v] = create(v,ff);
			maintain(ff);
			splay(tot); break;
		}
	}
}
int bargain(int k)
{
	int cur = root;
	while(1)
	{
		if(k <= siz[ch[cur][0]]) cur = ch[cur][0];
		else if(siz[ch[cur][0]] + cnt[cur] >= k) return val[cur];
		else
		{
			k -= siz[ch[cur][0]] + cnt[cur]; 
			cur = ch[cur][1];
		} 
	}
}
int rankle(int v)
{
	int cur = root,ans = 0;
	while(1)
	{
		if(not cur) return ans + 1;
		if(v < val[cur]) cur = ch[cur][0];
		else if(v == val[cur])
		{
			ans += siz[ch[cur][0]];
			splay(cur);
			return ans + 1;
		}
		else 
		{
			ans += siz[ch[cur][0]] + cnt[cur];
			cur = ch[cur][1];
		}
	}
}
int charge()
{
	int cur = ch[root][0];
	while(ch[cur][1]) cur = ch[cur][1];
	return cur;
}
int recoil()
{
	int cur = ch[root][1];
	while(ch[cur][0]) cur = ch[cur][0];
	return cur;
}
void reliese(int v)
{
	rankle(v);
	if(cnt[root] > 1)
	{
		cnt[root]--; maintain(root);
		return ;
	}
	else if(not ch[root][0] and not ch[root][1])
	{
		root = 0;
		return ;
	}
	else if(not ch[root][0])
	{
		root = ch[root][1];
		fa[root] = 0;
		return ;
	}
	else if(not ch[root][1])
	{
		root = ch[root][0];
		fa[root] = 0;
		return ;
	}
	int tmp = ch[root][1],pre = charge();
	splay(pre);
	fa[tmp] = root;
	ch[root][1] = tmp;
	maintain(root);
}
signed main()
{
	scanf("%lld",&n);
	for(int i = 1;i <= n;i++)
		scanf("%lld%lld",&opt[i],&spe[i]);
	for(int i = 1;i <= n;i++)
	{
		if(pet == cus) ins(spe[i]);
		else if(pet < cus)
		{
			if(opt[i]) ins(spe[i]);
			else
			{
				ins(spe[i]);
				rankle(spe[i]);
				int pre = charge(),suf = recoil();
				if(not pre)
				{
					res = (res + labs(spe[i] - val[suf])) % mod;
					reliese(val[suf]);
				}
				else if(not suf)
				{
					res += labs(spe[i] - val[pre]);
					res %= 1000000;
					reliese(val[pre]);
				}
				else
				{
					if(labs(spe[i] - val[pre]) <= labs(spe[i] - val[suf])) res += labs(spe[i] - val[pre]),res %= 1000000,reliese(val[pre]);
					else res += labs(spe[i] - val[suf]), res %= 1000000,reliese(val[suf]);
				}
				reliese(spe[i]);
			}
		}
		else 
		{
			if(not opt[i]) ins(spe[i]);
			else
			{
				ins(spe[i]);
				rankle(spe[i]);
				int pre = charge(),suf = recoil();
				if(not pre)
				{
					res += labs(spe[i] - val[suf]);
					res %= 1000000;
					reliese(val[suf]);
				}
				else if(not suf)
				{
					res += labs(spe[i] - val[pre]);
					res %= 1000000;
					reliese(val[pre]);
				}
				else
				{
					if(labs(spe[i] - val[pre]) <= labs(spe[i] - val[suf])) res += labs(spe[i] - val[pre]),res %= 1000000,reliese(val[pre]);
					else res += labs(spe[i] - val[suf]), res %= 1000000,reliese(val[suf]);
				}
				reliese(spe[i]);
			}
		}
		opt[i] ? cus++ : pet++;
		//cout << res << endl;
	}
	printf("%lld\n",res);
	return 0;
}

标签:ch,cur,int,宠物,Splay,fa,ff,root,P2286
来源: https://www.cnblogs.com/snowlovers/p/15656170.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有