[HNOI2002]营业额统计【splay模板】

版权声明:https://blog.csdn.net/qq_41730082 https://blog.csdn.net/qq_41730082/article/details/87943517

题目链接

关于splay的知识点的讲解


  一道基础的splay的题,虽然也可以去用stl去做,但是既然是锻炼splay的思想就是去用splay来写了,我们每次都要去寻找到前驱和后继,当然第一个点例外,我们直接加上第一个点的值就是了,然后,我们去找每个点的前驱和后继,但是呢,为了不遇到0前驱和0后继的情况,我加上了一个最小值与最大值来回避了这个问题(最小值可能取负值)。然后如果对应的前驱或者是后继存在或者是存在该值的点,我们逐一判断最小差值就是了。

当然,要是这道题不标上是splay的模板题,我绝对是想不到的…… 


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e6 + 7;
int N, root, tot;
struct node
{
    int ff, val, cnt, size, ch[2];
    node() { ff = val = size = ch[0] = ch[1] = 0; }
    void init(int vv, int fa)
    {
        ff = fa;    val = vv;
        ch[0] = ch[1] = 0;
        size = cnt = 1;
    }
}t[maxN];
void pushup(int rt) { t[rt].size = t[t[rt].ch[0]].size + t[t[rt].ch[1]].size + 1; }
void rotate(int x)
{
    int y = t[x].ff, z = t[y].ff;
    int k = t[y].ch[1] == x;
    t[z].ch[t[z].ch[1] == y] = x;
    t[x].ff = z;
    t[y].ch[k] = t[x].ch[k^1];
    t[t[x].ch[k^1]].ff = y;
    t[x].ch[k^1] = y;
    t[y].ff = x;
    pushup(y);  pushup(x);
}
void splay(int x, int goal)
{
    while(t[x].ff != goal)
    {
        int y = t[x].ff, z = t[y].ff;
        if(z != goal) (t[z].ch[0] == y) ^ (t[y].ch[0] == x) ? rotate(x) : rotate(y);
        rotate(x);
    }
    if(!goal) root = x;
}
void Find(int x)
{
    int u = root;
    if(!u) return;
    while(t[u].ch[x>t[u].val] && x != t[u].val) u = t[u].ch[x>t[u].val];
    splay(u, 0);
}
void insert(int x)
{
    int u = root, ff = 0;
    while(u && t[u].val != x)
    {
        ff = u;
        u = t[u].ch[x>t[u].val];
    }
    if(u) t[u].cnt++;
    else
    {
        u = ++tot;
        if(ff) t[ff].ch[x>t[ff].val] = u;
        t[u].init(x, ff);
    }
    splay(u, 0);
}
int Next(int x, int f)
{
    Find(x);
    int u  = root;
    if(t[u].val > x && f) return u;
    if(t[u].val < x && !f) return u;
    u = t[u].ch[f];
    while(t[u].ch[f^1]) u = t[u].ch[f^1];
    return u;
}
int work(int x)
{
    int last = Next(x, 0), next = Next(x, 1);
    splay(last, 0);
    splay(next, last);
    int now = t[next].ch[0];
    if(now) return 0;
    else return min(abs(x - t[last].val), abs(x - t[next].val));
}
int main()
{
    scanf("%d", &N);
    root = tot = 0;
    int ans = 0;
    insert(-INF);
    insert(INF);
    scanf("%d", &ans);
    insert(ans);
    for(int i=2, j; i<=N; i++)
    {
        scanf("%d", &j);
        ans += work(j);
        insert(j);
    }
    printf("%d\n", ans);
    return 0;
}
/*
6
5
1
2
5
4
6
 ans:12
*/

猜你喜欢

转载自blog.csdn.net/qq_41730082/article/details/87943517