BZOJ1588 [HNOI2002]营业额统计 set
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ1588
题意概括
给出数列,求 ∑F[i],其中F[1] = a[1] , F[i] = min( |a[i] - a[j]| ) (j<i)
题解
只需要每次可以求那个东西就可以了。
那么我们搞一个set,每次把数字放到set里面。
查询就是lower_bound,这样就可以找到与这个数字差值可能最小的。
然后只有两个可能,一个是lower_bound到的那个,一个是lower_bound之前的那个,都有可能为最优的,所以min一下就可以了。
but,我不理解,为什么网上几乎都是treap、splay的解法,代码实在长,那些大佬博主(Orz)还说简单……
代码
#include <cstring> #include <algorithm> #include <cstdio> #include <cmath> #include <cstdlib> #include <set> using namespace std; int n,ans; set <int> S; int main(){ S.clear(); S.insert(1<<28); S.insert(-(1<<28)); scanf("%d",&n); ans=0; for (int i=1,x;i<=n;i++){ scanf("%d",&x); set <int> :: iterator p=S.lower_bound(x); int a=-1,b=-1; if (i==1) ans+=abs(x); else ans+=min(abs(x-*(--p)),abs(x-*p)); S.insert(x); } printf("%d",ans); return 0; }