[BZOJ1588][HNOI2002][Treap][Splay]营业额统计[水题]

题意:

    给出N天的营业额,定义某天营业额的“最小波动值”为这天之前所有营业额与该天营业额之差的绝对值的最小值。特别地,第一天营业额的“最小波动值”即为第一天营业额本身。
    实质:给定一个序列 {ai} ,求:

a1+2inminj<i{aiaj}

解法:

    如果顺序记下每天的营业额并使之有序的话,我们会发现,每加入一天的营业额,它的前驱和后继与它差值之中小的一个即为这一天的“最小波动值”,累加答案即可。
    因此我们可以用BST维护营业额,每插入一个数就查询前驱和后继。但是在实践中有一种编程复杂度更低,而效果很好的方法:用插入时走过的路径上的所有点维护答案即可,正确性显然。
    (不要随便看代码。不要随便看代码。不要随便看代码。因为很重要所以说三次。)

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <ctime>
using namespace std;

//Global Variables & Definitions
int N;

inline int iabs(int a) {
    return a > 0 ? a : -a;
}
//End Global Variables & Definitions

//Treap
struct node {
    node *ch[2];
    int v;
    int r;

    node() : r(rand()) { ch[0] = ch[1] = NULL; }
    node(int v) : v(v), r(rand()) { ch[0] = ch[1] = NULL; }

    int cmp(int va) {
        return va < this -> v ? 0 : 1;
    }
};

void Rotate(node* & o, int d) {
    node *k = o -> ch[d ^ 1];
    o -> ch[d ^ 1] = k -> ch[d];
    k -> ch[d] = o;
    o = k;
}

int Insert(node* & o, int v) {
    int t = iabs(v - o -> v), t2 = 0x7fffffff;
    int d = o -> cmp(v);

    if(o -> ch[d] == NULL) {
        o -> ch[d] = new node(v);
    } else {
        t2 = Insert(o -> ch[d], v);
    }

    if(o -> r < o -> ch[d] -> r) Rotate(o, d ^ 1);
    return min(t, t2);
}
//End Treap

//Main Structure
node *root;

inline void ir() {
    //srand(time(NULL));
    srand(20150423);
    scanf("%d", &N);
}

int main() {
    ir();

    int ans = 0, temp;

    //1st
    if(!~scanf("%d", &temp)) temp = 0;
    ans = temp;
    root = new node(temp);

    //else
    for(int i = 1;i < N;++i) {
        if(!~scanf("%d", &temp)) temp = 0;

        ans += Insert(root, temp);
    }

    printf("%d\n", ans);
    return 0;
}

    在BZOJ上srand(time(NULL))奇怪的RE了,所以随便指定了一个种子。
    傲娇的BZOJ又抽风

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值