来自HNOI 2002营业额的统计一题,这题以前是用链表水过的,最近看见许多splay的题,赶紧张一下知识。

题目大意就是对于一个序列,输出每个元素与它之前元素的差的最小值的和。先说链表的方法吧。

大概就是sort一下,记录每个点的rank。然后链表一下,很好理解,复杂度nlogn,瓶颈在于排序。

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
struct node
{
int l,r,val,pos;
bool operator <(node b)
{
return val<b.val;
}
}a[];
int rank[];
int main()
{
int n;
cin>>n;
for(int i=;i<=n;++i)
{
scanf("%d",&a[i].val);a[i].pos=i;
}
sort(a+,a++n);
for(int i=;i<=n;++i)
{
a[i].l=i-;a[i].r=i+;
rank[a[i].pos]=i;
}
a[n].r=;
int ans=a[rank[]].val;
for(int i=n;i>;--i)
{
int x=rank[i];
if(a[x].l&&a[x].r)
{
ans+=min(abs(a[x].val-a[a[x].r].val),abs(a[x].val-a[a[x].l].val));
a[a[x].r].l=a[x].l;a[a[x].l].r=a[x].r;
}
else if(a[x].l)
{
ans+=abs(a[x].val-a[a[x].l].val);
a[a[x].l].r=a[x].r;
}
else
{
ans+=abs(a[x].val-a[a[x].r].val);
a[a[x].r].l=a[x].l;
}
}
cout<<ans<<endl;
}

接下来是Splay啦!

先上代码

#include<bits/stdc++.h>
using namespace std;
struct tree
{
int l,r,w,fa;
}t[];
bool flag;
int cnt,root;
inline void read(int &x)
{
x=;int p=; char ch;ch=getchar();
while(ch<''||ch>'') {if(ch=='-') p=-p; ch=getchar();}
while(ch>=''&&ch<='') {x=x*+ch-'';ch=getchar();}
x=x*p;
}
inline void build(int x,int pos)
{
if(x==t[pos].w) {flag=;return;}
if(x<t[pos].w)
{
if(!t[pos].l)
{t[pos].l=++cnt;t[cnt].w=x;t[cnt].fa=pos;return;}
build(x,t[pos].l);
}
else
{
if(!t[pos].r)
{t[pos].r=++cnt;t[cnt].w=x;t[cnt].fa=pos;return;}
build(x,t[pos].r);
}
}
inline void rotate(int x,int &k)
{
int y=t[x].fa,z=t[y].fa;
if(y==k) k=x;
else
{
if(t[z].l==y) t[z].l=x;
else t[z].r=x;
}
if(t[y].l==x) t[t[x].r].fa=y,t[y].l=t[x].r,t[x].r=y;
else t[t[x].l].fa=y,t[y].r=t[x].l,t[x].l=y;
t[y].fa=x;t[x].fa=z;
}
inline void splay(int x,int &k)
{
while(x!=k)
{
int y=t[x].fa,z=t[y].fa;
if(y!=k)
{
if((t[z].l==y)^(t[y].l==x)) rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
inline int queryl(int x)
{
x=t[x].l;if(!x) return x;
while(t[x].r) x=t[x].r;
return x;
}
inline int queryr(int x)
{
x=t[x].r;if(!x) return x;
while(t[x].l) x=t[x].l;
return x;
}
inline int insert(int x)
{
flag=;
build(x,root);
if(flag) return ;
splay(cnt,root);
int l=queryl(cnt),r=queryr(cnt);
int ans=1e9;
if(l) ans=min(ans,abs(t[l].w-x));
if(r) ans=min(ans,abs(t[r].w-x));
return ans;
}
int main()
{
int n,x;
read(n);
int ans=;
read(x);
ans=x;
++cnt;t[cnt].w=x;root=cnt;
for(int i=;i<n;++i)
{
read(x);
ans+=insert(x);
}
printf("%d",ans);
}

这里用splay维护bst,这样每次可以查询一个元素的前驱和后继,做减法取个min即可。这时我们就需要splay操作了。splay的核心操作就是旋转,这里可以参考墩爷爷的博客,他介绍的非常详细。http://blog.csdn.net/skydec/article/details/20151805

插入一个元素,把他rotate到根的位置,这样可以保证平均复杂度是nlogn的(虽然我不会证明),然后进行简单的bst遍历即可。rotate操作每次可以左旋或右旋一个节点,每次rotate需要改变父亲与儿子的从属关系,这个操作与树的形态有关系,有两种情况:一种是一条链的情况,一种就相反。强烈建议去墩爷爷的博客去看一下,我实在是懒得写了。但是splay常数实在是大,bzoj上比链表那个慢了1s+,在luogu上t了一个点=。=数据结构代码量大,还不好调试。但是学长说的好啊,多学数据结构可以弥补智商的不足=。=

bzoj 1588 [HNOI2002] 营业额统计 链表和Splay的更多相关文章

  1. BZOJ 1588: [HNOI2002]营业额统计 双向链表

    BZOJ 1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 512 MBSubmit: 9619  Solved: 3287 题目连接 ht ...

  2. BZOJ 1588: [HNOI2002]营业额统计 双向链表 / splay / treap

    1588: [HNOI2002]营业额统计 Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger ...

  3. 数据结构:(平衡树,链表)BZOJ 1588[HNOI2002]营业额统计

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 12173  Solved: 4354[Submit][Sta ...

  4. Bzoj 1588: [HNOI2002]营业额统计(splay)

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MB Description 营业额统计 Tiger最近被公司升任为营业部经理,他上 ...

  5. BZOJ 1588: [HNOI2002]营业额统计

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 14396  Solved: 5521[Submit][Sta ...

  6. bzoj 1588: [HNOI2002]营业额统计 treap

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 13902  Solved: 5225[Submit][Sta ...

  7. 2018.07.06 BZOJ 1588: HNOI2002营业额统计(非旋treap)

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MB Description 营业额统计 Tiger最近被公司升任为营业部经理,他上 ...

  8. SET || BZOJ 1588: [HNOI2002]营业额统计 || Luogu P2234 [HNOI2002]营业额统计

    题面:P2234 [HNOI2002]营业额统计 题解:随便写写 注意:cmath中abs函数返回的是一个浮点数,在bzoj上会ce 代码: #include<cstdio> #inclu ...

  9. 1588. [HNOI2002]营业额统计【平衡树-splay 或 线段树】

    Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每 ...

随机推荐

  1. 还是bib问题

    虽然昨天把添加bib的基本问题解决了,但是bib的参考文献没有了中括号.查了一下华东师大,只是给出了如何去掉中括号的方法. http://math.ecnu.edu.cn/~latex/doc.htm ...

  2. EL与JSTL学习(二)——JSTL技术

    1.JSTL概述 JSTL(JSP Standard Tag Library),JSP标准标签库,可以嵌入在jsp页面中使用标签的形式完成业务逻辑等功能. jstl出现的目的同el一样也是要代替jsp ...

  3. Servlet学习(三)——实例:用户登录并记录登陆次数

    1.前提:在Mysql数据库下建立数据库web13,在web13下创建一张表user,插入几条数据如下: 2.创建HTML文件,命名为login,作为登录界面(以post方式提交) <!DOCT ...

  4. Analysis of the Facebook.app for iOS

    Analysis of the Facebook.app for iOS Posted Oct 18, 2016 Did you ever wonder why the Facebook.app fo ...

  5. STM8S103 STVD编译空间不足

    关于text空间(理解为代码空间)不足问题 # 关于.bsct和.ubsct问题(着重参考http://www.waveshare.net/article/STM8-3-1-10.htm) map文件 ...

  6. Git常见问题 资料汇总

    来源https://blog.csdn.net/albb_/article/details/80420468

  7. springMVC小项目实例

    一.什么是 Spring MVC Spring MVC 属于 SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 里面,是一个强大灵活的 Web 框架.Spring ...

  8. document.body

    比如document.body,最好是写成document.getElementsByTagName("body")[0];

  9. luogu P1869 愚蠢的组合数(质因数+瞎搞)

    题意 n<=105 题解 一个数是不是偶数就是看有没有二这个质因子. 所以我们先预处理每个数的阶乘的二这个质因子的数量 然后按公式判断就行了. #include<iostream> ...

  10. c traps and pitfalls reading note(1)

    1. 一直知道char *p = 'a';这样写是错误的,但是为什么是错的,没想过,今天看书解惑. p指向一个字符,但是在c中,''引起来的一个字符代表一个整数,这样指针能不报错.o(^▽^)o 2. ...