来自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. Ubuntu16.04+GTX 1080Ti+CUDA 8.0+cuDNN+Tesnorflow1.0深度学习服务器安装之路

    0.安装背景 系统:ubuntu 16.04 内核:4.4.0-140-generic GPU:GTX 1080Ti nvidia驱动版本: 384.111 cuda: CUDA 8.0 深度学习库c ...

  2. Linux基础02

    ** Linux基本操作常用命令(二) ** 用户名与主机名 当你进入Linux终端时,你会看到如下样式的图片:     其中[z@z01]方括号内的z表示当前系统登录操作的用户名,@后的z01表示当 ...

  3. mybatis的sql中字段两种映射(映射到实体)方式

    mybatis的xml配置文件中,字段映射的两种方式: 1.resultMap标签中将数据库的字段与实体类中的字段对应: <resultMap id="BaseResultMap&qu ...

  4. jQuery EasyUI 右键菜单--关闭标签/选项卡

    目录结构: noContextMenu.js 文件内容如下: $(function(){ //屏蔽右键菜单 $(document).bind("contextmenu", func ...

  5. Optional是以enum和泛型为基础的高阶类型

    结论:1.optionals使用时需要检查:2.可以通过!+赋值语句转化为非optionals. Optional-Generic Enumeration enum Optional<T> ...

  6. How Javascript works (Javascript工作原理) (三) 内存管理及如何处理 4 类常见的内存泄漏问题

    个人总结: 1.两种垃圾回收机制: 1)引用标记算法:如果检测到一个对象没有被引用了,就清除它. ***这种算法不能处理循环引用的情况*** 2)标记—清除算法:从根(全局变量)开始向后代变量检测,任 ...

  7. POJ 3134 Power Calculus (迭代剪枝搜索)

    题目大意:略 题目里所有的运算都是幂运算,所以转化成指数的加减 由于搜索层数不会超过$2*log$层,所以用一个栈存储哪些数已经被组合出来了,不必暴力枚举哪些数已经被搜出来了 然后跑$iddfs$就行 ...

  8. Java将WKT格式的Geomotry转换成GeoJSON

    一.Meven添加依赖 <!-- 引入json处理包 --> <dependency> <groupId>com.alibaba</groupId> & ...

  9. HTTP——学习笔记(8)

    HTTP中的一些协议内容会限制某些网站的功能使用 比如,Facebook这类的社交网站,需要实时地观察到海量用户公开发布的内容,而HTTP中的以下标准就会成为瓶颈: 一条连接上只可发送一个请求 请求只 ...

  10. Docker学习总结(10)——10分钟玩转Docker

    1.前言 进入云计算的时代,各大云提供商AWS,阿里云纷纷推出针对Docker的服务,现在Docker是十分火爆,那么Docker到底是什麽,让我们来体验一下. 2.Docker是什麽 Docker是 ...