Splay 入门题

H - 营业额统计

解题方法:
  每次找 min(大于a的最小值, 小于a 的最大值)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<math.h>
using namespace std;
const int maxn=500010;
const int inf=0x3f3f3f3f;

struct SplayTree
{
    int rt,id;
    int son[maxn][2],val[maxn],pre[maxn];
    void Rotate(int x,int c)
    {
        int y=pre[x];
        son[y][!c]=son[x][c];
        pre[son[x][c]]=y;
        pre[x]=pre[y];
        if(pre[y])   son[pre[y]][son[pre[y]][1]==y]=x;
        son[x][c]=y;
        pre[y]=x;
    }
    void Splay(int x,int goal)
    {
        while(pre[x]!=goal)
        {
            if(pre[pre[x]]==goal)
            {
                if(son[pre[x]][1]==x)
                    Rotate(x,0);
                else
                    Rotate(x,1);
            }
            else{
                int y=pre[x];
                int z=pre[y];
                if(son[z][0]==y){
                    if(son[y][0]==x){
                        Rotate(y,1),Rotate(x,1);
                    }
                    else {
                        Rotate(x,0),Rotate(x,1);
                    }
                }
                else {
                    if(son[y][1]==x){
                        Rotate(y,0),Rotate(x,0);
                    }
                    else {
                        Rotate(x,1),Rotate(x,0);
                    }
                }
            }
        }
        if(goal==0)  rt=x;
    }
    void Newnode(int f,int &x,int a)
    {
        x=++id;
        pre[x]=f;
        val[x]=a;
        son[x][0]=0,son[x][1]=0;
    }
    void Init()
    {
         id=0;
        Newnode(0,rt,-inf);
        Newnode(rt,son[rt][1],inf);
    }
    void Insert(int a)
    {
        int x=rt;
        while(son[x][val[x]<a])  x=son[x][val[x]<a];
        Newnode(x,son[x][val[x]<a],a);
        Splay(id,0);
    }
    int  fx_min(int a)
    {
        int x=rt;
        int Min=inf;
        while(x){
            if(val[x]==a)  return a;
            if(val[x]>a)  Min=min(Min,val[x]);
            if(val[x]>a)  x=son[x][0];
            else
                x=son[x][1];
        }
        return Min;
    }
    int fx_max(int a)
    {
        int x=rt;
        int Max=-inf;
        while(x){
            if(val[x]==a) return a;
            if(val[x]<a)  Max=max(Max,val[x]);
            if(val[x]<a)
                x=son[x][1];
            else
                x=son[x][0];
        }
        return Max;
    }
}spy;

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif // ONLINE_JUDGE
    int n,a,ans;
     scanf("%d%d",&n,&a);
        spy.Init();
        spy.Insert(a);
        ans=a;
        while(--n)
        {
            if(scanf("%d",&a)==EOF) a=0;
            ans+=min(fabs(a-spy.fx_min(a)),fabs(a-spy.fx_max(a)));
            spy.Insert(a);
        }
        printf("%d\n",ans);
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-31 14:39:55

Splay 入门题的相关文章

BZOJ1588 HNOI2002 营业额统计 [Splay入门题]

[HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 4128  Solved: 1305 Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况是一项相当复杂的工作.由于节假日,大减价或者是其他情况的时候,营业 额会出现一定的波动,当然一定的波动是能够接受

hdu 2767 Proving Equivalences(强连通入门题)

1 /************************************************* 2 Proving Equivalences(hdu 2767) 3 强连通入门题 4 给个有向图,求至少加多少条边使得图是所有点都是强连通的 5 由a->b->c->a易知n个点至少要n条边,每个出度和入度都要大 6 于1.先求所有所有强连通分量,把每个强连通分量看成一个点 7 在找每个点的出度和入度,最后还差的出度和入度的最大值就是 8 答案. 9 10 ************

hdu 5001 walk 概率dp入门题

Description I used to think I could be anything, but now I know that I couldn't do anything. So I started traveling. The nation looks like a connected bidirectional graph, and I am randomly walking on it. It means when I am at node i, I will travel t

hdu1796:容斥入门题

简单的容斥入门题.. 容斥基本的公式早就知道了,但是一直不会写. 下午看到艾神在群里说的“会枚举二进制数就会容斥”,后来发现还真是这样.. 然后直接贴代码了 #include <iostream> #include <stdio.h> #include<string.h> #include<algorithm> #include<string> #include<ctype.h> using namespace std; long l

hdu1695 GCD(莫比乌斯入门题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意: 给出n.m.k ,求出1<=x<=n, 1<=y<=m 且gcd(x,y) == k 的(x,y)的对数 解析: 显然就是求 [1,n/k] 与 [1, m/k]有多少数对的最大公约数是1 莫比乌斯入门题 我们设 为满足且和的的对数 为满足且和的的对数 那么,很显然,反演后得到 我们所需要的答案便是  f(1) = ∑i=1μ(i)*(n/i)*(m/i)  ,求解这个式

网络流最经典的入门题 各种网络算法都能AC。

Drainage Ditches 题目抽象:给你m条边u,v,c.   n个定点,源点1,汇点n.求最大流.  最好的入门题,各种算法都可以拿来练习 (1):  一般增广路算法  ford() 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string&g

hdu 1754:I Hate It(线段树,入门题,RMQ问题)

I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 33726    Accepted Submission(s): 13266 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感.不管你喜不喜欢,现在需要你做的是,就是按照老师的要求

hdu 1162 Eddy&#39;s picture 最小生成树入门题 Prim+Kruskal两种算法AC

Eddy's picture Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7428    Accepted Submission(s): 3770 Problem Description Eddy begins to like painting pictures recently ,he is sure of himself to

COGS 577 蝗灾 [CDQ分治入门题]

题目链接 昨天mhr神犇,讲分治时的CDQ分治的入门题. 题意: 你又一个w*w正方形的田地. 初始时没有蝗虫. 给你两个操作: 1. 1 x y z: (x,y)这个位置多了z只蝗虫. 2. 2 x1 y1 x2 y2: 询问(x1,y1)到(x2,y2)这个矩形内的蝗虫数量. 其中 W<=500000,操作数<=200000 . 题解: w范围太大,无法使用二维数据结构. 于是我们可以分治操作. CDQ分治:定义 solve(l,r) 设m=(l+r)/2; 先计算 l-m 修改操作对 m