• P2234 [HNOI2002]营业额统计


    题面传送门

    题意:对于N天的营业额,你需要求出每天营业额与当天前的营业额差值的最小值的和。

    思路:感觉挺裸的SBT,对于每天的营业额x,插值,求x与x的前驱的差值d1,求x的后继与x的差值d2(ps:这里的前驱后继的可以等于x),用一个treap就可以过了。


    Code:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    //Mystery_Sky
    //
    #define M 1000100
    #define INF 0x3f3f3f3f
    #define ll long long
    inline int read()
    {
    	int x = 0,f=1; char c=getchar();
    	while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
    	return x*f;
    }
    struct Treap{
    	int size, cnt;
    	int l, r;
    	int dat, val;
    }a[M];
    
    int tot, root, n, ans;
    
    inline int New(int val)
    {
    	a[++tot].val = val;
    	a[tot].dat = rand();
    	a[tot].cnt = a[tot].size = 1;
    	return tot;
    }
    
    inline void update(int p)
    {
    	a[p].size = a[a[p].l].size + a[a[p].r].size + a[p].cnt;
    }
    
    inline void build()
    {
    	root = New(-INF);
    	a[root].r = New(INF);
    	update(root);
    }
    
    inline void right_Rotate(int &p)
    {
    	int k = a[p].l;
    	a[p].l = a[k].r, a[k].r = p, p = k;
    	update(a[p].r);
    	update(p);
    }
    
    inline void left_Rotate(int &p)
    {
    	int k = a[p].r;
    	a[p].r = a[k].l, a[k].l = p, p = k;
    	update(a[p].l);
    	update(p);
    }
    
    void insert(int &p, int val)
    {
    	if(!p) {
    		p = New(val);
    		return;
    	}
    	if(val == a[p].val) {
    		a[p].cnt++;
    		update(p);
    		return;	
    	}
    	else if(val < a[p].val) {
    		insert(a[p].l, val);
    		if(a[p].dat < a[a[p].l].dat) right_Rotate(p);
    	}
    	else {
    		insert(a[p].r, val);
    		if(a[p].dat > a[a[p].r].dat) left_Rotate(p);
    	}
    	update(p);
    }
    
    int query_pre(int val)
    {
    	int ans = a[root].val;
    	int p = root;
    	while(p) {
    		if(a[p].val == val && a[p].cnt > 1) return val;
    		if(a[p].val < val) ans = a[p].val, p = a[p].r;
    		else p = a[p].l;			
    	}
    	return ans;
    }
    
    inline int query_next(int val)
    {
    	int ans = a[root].val;
    	int p = root;
    	while(p) {
    		if(a[p].val == val && a[p].cnt > 1) return val;
    		if(a[p].val > val) ans = a[p].val, p = a[p].l;
    		else p = a[p].r;
    	}
    	return ans;
    }
    
    int main() {
    	n = read();
    	build();
    	for(int i = 1; i <= n; i++) {
    		int x = read();
    		if(i == 1) ans += x, insert(root, x);
    		else {
    			insert(root, x);
    			int d1 = abs(x - query_pre(x));
    			int d2 = abs(query_next(x) - x);
    			//printf("%d %d
    ", d1, d2);
    			ans += min(d1, d2);
    		}
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    五分钟搞懂Vuex
    vue 背景图片 backgroundImage background-image vue的style方式绑定行内样式-background-image的方式等~
    VUE2.0 vue-cli构建项目中使用Less
    ES6如何引入图片
    Vue+Gojs实现流程图demo
    vue自定义指令要点
    vue cli中token验证
    linux服务器上配置多个svn仓库
    vue-cli(vue脚手架)超详细教程
    node学习第一天:nvm使用
  • 原文地址:https://www.cnblogs.com/Benjamin-cpp/p/11515448.html
Copyright © 2020-2023  润新知