zoukankan      html  css  js  c++  java
  • 【题解】 P2234 [HNOI2002]营业额统计

    平衡树板题

    原题传送门

    这道题要用Splay,我博客里有对Splay的详细介绍

    这道题目还算比较模板的

    每输入一个数,先不要插入

    要求一下前驱和后继与x差的最小值并加到答案中

    再把x插入平衡树

    然后你会发现过不了样例

    发现相同的数字是会有的

    所以还要写find函数,要多加一个变量来比最小:

    find(x)!=0?0:inf;
    

    剩下就没什么问题了qaq

    #pragma GCC optimize("O3")
    #include <bits/stdc++.h>
    #define root tree[0].ch[1]
    #define inf 1000000005
    using namespace std;
    inline int read()
    {
    	register int x=0,f=1;register char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return x*f;
    }
    inline int Min(register int a,register int b)
    {
    	return a<b?a:b;
    }
    struct Splay{
    	int fa,ch[2],sum,rec,v;
    }tree[32780];
    int tot=0;
    inline bool findd(register int x)
    {
    	return x==tree[tree[x].fa].ch[0]?0:1;
    }
    inline void connect(register int x,register int fa,register int son)
    {
    	tree[x].fa=fa;
    	tree[fa].ch[son]=x;
    }
    inline void update(register int x)
    {
    	tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].rec;
    }
    inline void rotate(register int x)
    {
    	int Y=tree[x].fa;
    	int R=tree[Y].fa;
    	int Yson=findd(x);
    	int Rson=findd(Y);
    	int B=tree[x].ch[Yson^1];
    	connect(B,Y,Yson);
    	connect(Y,x,Yson^1);
    	connect(x,R,Rson);
    	update(Y),update(x);
    }
    inline void splay(register int x,register int to)
    {
    	to=tree[to].fa;
    	while(tree[x].fa!=to)
    	{
    		int y=tree[x].fa;
    		if(tree[y].fa==to)
    			rotate(x);
    		else if(findd(x)==findd(y))
    			rotate(y),rotate(x);
    		else
    			rotate(x),rotate(x);
    	}
    }
    inline int newpoint(register int v,register int fa)
    {
    	tree[++tot].v=v;
    	tree[tot].fa=fa;
    	tree[tot].sum=tree[tot].rec=1;
    	return tot;
    }
    inline void Insert(register int x)
    {
    	int now=root;
    	if(root==0)	
    	{
    		newpoint(x,0);
    		root=tot;
    	}
    	else
    	{
    		while(19260817)
    		{
    			++tree[now].sum;
    			if(x==tree[now].v)
    			{
    				++tree[now].rec;
    				splay(now,root);
    				return;
    			}
    			int nxt=x<tree[now].v?0:1;
    			if(!tree[now].ch[nxt])
    			{
    				int p=newpoint(x,now);
    				tree[now].ch[nxt]=p;
    				splay(p,root);
    				return;
    			}
    			now=tree[now].ch[nxt];
    		}
    	}
    }
    inline int find(register int v)
    {
    	int now=root;
    	while(19260817)
    	{
    		if(tree[now].v==v)
    		{
    			splay(now,root);
    			return now;
    		}
    		int nxt=v<tree[now].v?0:1;
    		if(!tree[now].ch[nxt])
    			return 0;
    		now=tree[now].ch[nxt];
    	}
    }
    inline int lower(register int v)
    {
    	int now=root;
    	int ans=-inf;
    	while(now)
    	{
    		if(tree[now].v<v&&tree[now].v>ans)
    			ans=tree[now].v;
    		if(v>tree[now].v)
    			now=tree[now].ch[1];
    		else
    			now=tree[now].ch[0];
    	}
    	return ans;
    }
    inline int upper(register int v)
    {
    	int now=root;
    	int ans=inf;
    	while(now)
    	{
    		if(tree[now].v>v&&tree[now].v<ans)
    			ans=tree[now].v;
    		if(v<tree[now].v)
    			now=tree[now].ch[0];
    		else
    			now=tree[now].ch[1];
    	}
    	return ans;
    }
    int main()
    {
    	int n=read();
    	int res=0;
    	for(register int i=1;i<=n;++i)
    	{
    		int x=read();
    		if(i==1)
    			res=x;
    		else
    			res+=Min(Min(fabs(lower(x)-x),fabs(upper(x)-x)),find(x)!=0?0:inf);
    		Insert(x);
    	}
    	printf("%d",res);
    	return 0;
     } 
    
  • 相关阅读:
    trie树
    基数排序
    CF724E Goods transportation 最小割 DP
    [CQOI2009]跳舞 网络流
    NOIP2018爆零记
    斜率优化
    CF311B Cats Transport 斜率优化DP
    逆元
    卡特兰数
    【BZOJ】【1565】【NOI2009】PVZ 植物大战僵尸
  • 原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/9959886.html
Copyright © 2011-2022 走看看