标签:
http://www.lydsy.com/JudgeOnline/problem.php?id=1588
给出每一天的营业值,求出之前的天当中与它相差最小的营业值与它的差的绝对值(第一天的差值为他本身),求和.
比宠物收养所更裸,果然十几年前的题都是水吗...然而我只会做水题.
注意:
1.第一次写Splay的时候重复的元素直接跳过导致一直T,后来就先把这个值伸展上来再跳过,就过了,果然这种均摊的复杂度不是可以瞎玩的...
另外,不判重似乎慢不了多少...
#include <cstdio> #include <cstdlib> #include <algorithm> using namespace std; const int oo=~0u>>1; struct Treap{ struct node{ node* ch[2]; int v,r; node(int v,node* t):v(v){ ch[0]=ch[1]=t; r=rand(); } }* root,* null; Treap(){ null=new node(0,NULL); null->r=oo; root=null; } void rot(node* &o,bool d){ node* k=o->ch[!d]; o->ch[!d]=k->ch[d]; k->ch[d]=o; o=k; } void insert(node* &o,int x){ if(o==null) o=new node(x,null); else{ if(x==o->v) return; bool d=x>o->v; insert(o->ch[d],x); if(o->ch[d]->r<o->r) rot(o,!d); } } int pre(node* o,int x){ if(o==null) return -oo; if(o->v<=x) return max(pre(o->ch[1],x),o->v); return pre(o->ch[0],x); } int suc(node* o,int x){ if(o==null) return oo; if(o->v>=x) return min(suc(o->ch[0],x),o->v); return suc(o->ch[1],x); } }tree; int n,a,ans; int main(){ scanf("%d",&n); scanf("%d",&a); ans+=a; tree.insert(tree.root,a); n--; while(n--){ if(scanf("%d",&a)==EOF) a=0; int pre=tree.pre(tree.root,a); int suc=tree.suc(tree.root,a); if(pre==-oo) ans+=suc-a; else if(suc==oo) ans+=a-pre; else ans+=min(suc-a,a-pre); tree.insert(tree.root,a); } printf("%d\n",ans); return 0; }
#include <cstdio> #include <algorithm> using namespace std; const int oo=~0u>>1; struct Splay{ struct node{ node* ch[2],*pa; int v; node(int v,node* t):v(v){ ch[0]=ch[1]=pa=t; } bool d(){ return pa->ch[1]==this; } void setc(node* t,bool d) { ch[d]=t; t->pa=this; } }*root,*null; Splay(){ null=new node(0,NULL); root=null; } void rot(node* o){ node* pa=o->pa; bool d=o->d(); pa->pa->setc(o,pa->d()); pa->setc(o->ch[!d],d); o->setc(pa,!d); if(pa==root) root=o; } void splay(node* o,node* pa){ while(o->pa!=pa){ if(o->pa->pa==pa) rot(o); else o->d()==o->pa->d()?(rot(o->pa),rot(o)):(rot(o),rot(o)); } } void insert(int x){ if(root==null){ root=new node(x,null); return; } node* t=root; if(t->v==x) return; while(t->ch[x>t->v]!=null&&t->ch[x>t->v]->v!=x) t=t->ch[x>t->v]; if(t->ch[x>t->v]!=null){ splay(t->ch[x>t->v],null); return; } node* k=new node(x,null); t->setc(k,x>t->v); splay(k,null); } int pre(int x){ node* t=root; int ret=-oo; while(t!=null){ if(t->v==x) return x; if(t->v<x) ret=t->v,t=t->ch[1]; else t=t->ch[0]; } return ret; } int suc(int x){ node* t=root; int ret=-oo; while(t!=null){ if(t->v==x) return x; if(t->v>x) ret=t->v,t=t->ch[0]; else t=t->ch[1]; } return ret; } }tree; int n,a,ans; int main(){ scanf("%d",&n); scanf("%d",&a); ans+=a; tree.insert(a); n--; while(n--){ if(scanf("%d",&a)==EOF) a=0; int pre=tree.pre(a); int suc=tree.suc(a); if(pre==-oo) ans+=suc-a; else if(suc==-oo) ans+=a-pre; else ans+=min(suc-a,a-pre); tree.insert(a); } printf("%d\n",ans); return 0; }
BZOJ_1588&Codevs_1296_[HNOI2002]_营业额统计(Treap/Splay)
标签:
原文地址:http://www.cnblogs.com/Sunnie69/p/5490350.html