题意:给定一个序列,维护:1、插入一个元素  2、求相邻两个元素中,差值绝对值的最小值  3、求序列排序后相邻两个元素中,差值绝对值的最小值

题解:

MIN_GAP:如果我们把数看成一组一组,每次插入数字都在一组的最后插入,那么答案只有可能在组内和组间两个位置产生,定义l[i]为一组数中最左边的数,r[i]为一组数中最右边的数,新插入的数为x,那么用|x-l[i]|取min来更新组内的最小值,|x-r[i]|强制更新组间的值。因此我们需要能单点修改,区间查询的数据结构,线段树走起。

MIN_SORT_GAP:由于答案与数的位置无关,Splay走起。显然与新插入的数x差值最小的数一定在插入过程走过的路经上(原因请自行脑补),开个ans维护答案即可。

这玩意比树套树啥的敲起来舒服多了

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <iostream>
#include <algorithm>
using namespace std;const int MAXN=500000+2;
int N,Q,ans=INT_MAX,l[MAXN],r[MAXN];
char S[20+2];//Segment Tree begin
typedef struct ST_NODE{int l,r,m;ST_NODE *lchild,*rchild;ST_NODE(){}ST_NODE(int _l,int _r):l(_l),r(_r),m(INT_MAX),lchild(0),rchild(0){}
} *ST_TREE;
ST_TREE ST_root;void ST_Pushup(ST_TREE &x){ x->m=min(x->lchild->m,x->rchild->m);}void ST_Build(ST_TREE &root,int l,int r){root=new ST_NODE(l,r);if(l==r) return;int m=(l+r)>>1;if(l<=m) ST_Build(root->lchild,l,m);if(m<r) ST_Build(root->rchild,m+1,r);
}void ST_Insert(ST_TREE &x,int p,int a,bool t){if(x->l==x->r){if(t) x->m=a;else x->m=min(x->m,a);return;}int m=(x->l+x->r)>>1;if(p<=m) ST_Insert(x->lchild,p,a,t);else ST_Insert(x->rchild,p,a,t);ST_Pushup(x);
}
//Segment Tree end//Splay Tree begin
typedef struct Splay_NODE{int v;Splay_NODE *child[2],*f;Splay_NODE(){}Splay_NODE(int _v,Splay_NODE *_f):v(_v),f(_f){}
} *Splay_TREE;
Splay_TREE Null,Splay_root;Splay_TREE NewNode(int v,Splay_TREE f){Splay_TREE x=new Splay_NODE(v,f);x->child[0]=x->child[1]=Null;return x;
}void Splay_Init(){Null=NewNode(INT_MAX,0);Splay_root=NewNode(INT_MAX>>1,Null);
}void Rotate(Splay_TREE &x,bool t){Splay_TREE y=x->f;y->child[!t]=x->child[t],x->child[t]->f=y,x->f=y->f;if(y->f->child[0]==y) y->f->child[0]=x;else y->f->child[1]=x;y->f=x,x->child[t]=y;if(y==Splay_root) Splay_root=x;
}void Splay(Splay_TREE &x,Splay_TREE &y){while(x->f!=y)if(x->f->f==y)if(x->f->child[0]==x) Rotate(x,1);else Rotate(x,0);else if(x->f->f->child[0]==x->f)if(x->f->child[0]==x) Rotate(x->f,1),Rotate(x,1);else Rotate(x,0),Rotate(x,1);elseif(x->f->child[0]==x) Rotate(x,1),Rotate(x,0);else Rotate(x->f,0),Rotate(x,0);
}void Splay_Insert(Splay_TREE &x,int a){Splay_TREE y=x,z;while(y!=Null){ans=min(ans,abs(a-y->v)),z=y;if(y->v>=a) y=y->child[0];else y=y->child[1];}if(z->v>=a) y=z->child[0]=NewNode(a,z);else y=z->child[1]=NewNode(a,z);Splay(y,Null);
}
//Splay Tree beginint main(){scanf("%d %d",&N,&Q);Splay_Init(),ST_Build(ST_root,1,2*N-1);for(int i=1;i<=N;i++){scanf("%d",l+i),r[i]=l[i];ST_Insert(ST_root,2*(i-1)+1,INT_MAX,0);if(i!=1) ST_Insert(ST_root,2*(i-1),abs(l[i-1]-l[i]),1);Splay_Insert(Splay_root,l[i]);}for(int i=1,x,y;i<=Q;i++){scanf("%s",S);if(strstr(S,"INSERT")){scanf("%d %d",&x,&y);ST_Insert(ST_root,2*(x-1)+1,abs(y-r[x]),0);if(x!=N) ST_Insert(ST_root,2*x,abs(y-l[x+1]),1);Splay_Insert(Splay_root,y);r[x]=y;}if(strstr(S,"MIN_GAP")) printf("%d\n",ST_root->m);if(strstr(S,"MIN_SORT_GAP")) printf("%d\n",ans);}return 0;
}

View Code

转载于:https://www.cnblogs.com/WDZRMPCBIT/p/6481635.html

BZOJ1058 ZJOI2007 报表统计 线段树+平衡树相关推荐

  1. BZOJ1058 [ZJOI2007]报表统计 set

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ1058.html 题目传送门 - BZOJ1058 题解 考虑用两个 multiset 分别维护两个答案 ...

  2. bzoj1058: [ZJOI2007]报表统计

    哈哈set卡时过了. set求前驱的方法:*--b.lower_bound(x) (想想写了splay的肉老师就很愉悦啊) 弄两个set,一个记录的是位置的值,一个是差值,MIN_SORT_GAP就很 ...

  3. 【BZOJ1058】[ZJOI2007]报表统计 STL

    [BZOJ1058][ZJOI2007]报表统计 Description 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一.经 ...

  4. bzoj 1058: [ZJOI2007]报表统计 (Treap)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1058 题面; 1058: [ZJOI2007]报表统计 Time Limit: 15 Sec ...

  5. bzoj 1058: [ZJOI2007]报表统计(set+multiset)

    1058: [ZJOI2007]报表统计 Time Limit: 15 Sec  Memory Limit: 162 MB Submit: 3774  Solved: 1284 [Submit][St ...

  6. CF 19D Points 【线段树+平衡树】

    在平面上进行三种操作: 1.add x y:在平面上添加一个点(x,y) 2.remove x y:将平面上的点(x,y)删除 3.find x y:在平面上寻找一个点,使这个点的横坐标大于x,纵坐标 ...

  7. P3919 【模板】可持久化数组(可持久化线段树/平衡树)

    题目描述 如题,你需要维护这样的一个长度为 N  的数组,支持如下几种操作 在某个历史版本上修改某一个位置上的值 访问某个历史版本上的某一位置的值 此外,每进行一次操作(对于操作2,即为生成一个完全一 ...

  8. Codeforces Round #740 (Div. 2) F. Top-Notch Insertions 线段树 / 平衡树 + 组合数学

    传送门 文章目录 题意: 思路: 题意: 思路: 考虑最终的序列是什么鸭子的,首先序列肯定单调不降,也就是a1≤a2≤a3≤...≤ana_1\le a_2\le a_3\le ...\le a_na ...

  9. [NOIp2017 Day2 T3] 列队phalanx(线段树 / 平衡树)

    题目 描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×mn×mn \times m名学生,方 ...

最新文章

  1. 32个笔画顺序表图片_32个笔画掌握透了,练字真的不难
  2. redis如何通过读写分离来承载读请求QPS超过10万多
  3. requests与urllib.request
  4. 算法题题目集合一,欢迎评论留言
  5. [转]nchar,char,varchar与nvarchar区别
  6. Sharepoint2007个人网站不能同步域信息的处理方法
  7. 设计模式——Iterator模式实现研究
  8. php 短信验证码对比,php短信验证码的3个优势,你知道是什么吗?
  9. 2Python全栈之路系列之MysQl基本数据类型
  10. 自动驾驶_感知_目标检测(基于图像)
  11. 类似c语言sizeof,sizeof()与strlen()在C语言中有什么不同
  12. 【人脸识别】基于matlab GUI BP神经网络人脸识别(含识别率)【含Matlab源码 891期】
  13. CMT 注册——Google Scholar Id,Semantic Scholar Id,和 DBLP Id
  14. 论文编写工具使用(1)latex软件
  15. 凹凸贴图、法线贴图、置换贴图
  16. Linux双网卡绑定bond0(单IP)
  17. 解密一个量化对冲基金开发人员的工作内容
  18. 运行BOA报错 Could not open mime.types file, /etc/mime.types, for reading
  19. bugku--秋名山车神速度要快
  20. 2009年6月Milk Hill的麦田圈预示巨大天体将靠近详细分析

热门文章

  1. cmd不能用的解决方法
  2. Android——Fragment介绍
  3. Linux 使用 yum 查看安装的软件包
  4. 使用docker的mysql镜像
  5. intellij出现dependency ‘xxx‘not found
  6. Exception in thread main java.lang.NoClassDefFoundError: org/apache/tez/dag/api/TezConfiguration
  7. jinja2语法中{%raw%}和{{}}的等效替换
  8. 等式约束和不等式约束下的KKT条件求法
  9. debian下面的apt-fast安装
  10. pytorch——torch.backends.cudnn.benchmark = True