[BZOJ1208/Luogu2286][HNOI2004]宠物收养场
题目链接:
就是一个平衡树裸题
维护一颗\(Splay/Treap/So\ on\),按照题意模拟查找前驱后继即可。
这里用\(std::set\)实现(难度\(--\)),当然你乐意手写我也没办法
时间复杂度 \(O(nlog_2n)\)
#include <set>
#include <cstdio>
#include <cctype>
#include <algorithm>
using std::set;
using std::lower_bound;
int n,ans,pre;
set<int> s;
inline int Getint()
{
register int x=0;
register char c=getchar();
while(!isdigit(c))c=getchar();
for(;isdigit(c);c=getchar())x=x*10+c-48;
return x;
}
int main()
{
n=Getint();
s.insert(0x7fffffff),s.insert(0x80000000);
for(int i=1;i<=n;i++)
{
int a=Getint(),b=Getint();
if(s.size()==2)pre=a,s.insert(b);
else if(a==pre)s.insert(b);
else
{
set<int>::iterator r=s.lower_bound(b),l=--r;
r++;
if(b-*l<=*r-b&&*l!=0x80000000)ans+=b-*l,s.erase(l);
else ans+=*r-b,s.erase(r);
}
ans%=1000000;
}
printf("%d\n",ans);
return 0;
}