p1110 报表统计(FHQ-TREAP/TREAP)
平衡树的裸题,操作都相当简单
写了一个FHQ,但是奈何常数太大,实在过不去
最后写了一个Treap开O2水过
TREAP代码
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <ctime>
using namespace std;
struct node{
int sz,key,ran,l,r,re;
}tr[500100<<2];
int maxsize=0,ans=0,root1=0,root2=0,fir[500100],back[500100],min3=0x3f3f3f3f;
void update(int k){
tr[k].sz=tr[tr[k].l].sz+tr[tr[k].r].sz+tr[k].re;
}
void roratel(int &o){
int k=tr[o].r;
tr[o].r=tr[k].l;
tr[k].l=o;
tr[k].sz=tr[o].sz;
update(o);
o=k;
}
void rorater(int &k){
int o=tr[k].l;
tr[k].l=tr[o].r;
tr[o].r=k;
tr[o].sz=tr[k].sz;
update(k);
k=o;
}
void insert(int &k,int x){
if(k==0){
++maxsize;
k=maxsize;
tr[k].sz=1;
tr[k].re=1;
tr[k].key=x;
tr[k].ran=rand();
return;
}
tr[k].sz++;
if(tr[k].key==x){
tr[k].re++;
}
else{
if(x>tr[k].key){
insert(tr[k].r,x);
if(tr[tr[k].r].ran<tr[k].ran)
roratel(k);}
else{
insert(tr[k].l,x);
if(tr[tr[k].l].ran<tr[k].ran)
rorater(k);}
}
}
void del(int &k,int x){
if(k==0)
return;
if(tr[k].key==x){
if(tr[k].re>1){
tr[k].re--;
tr[k].sz--;
return;
}
if(tr[k].l*tr[k].r==0){
k=tr[k].l+tr[k].r;
return;
}
else{
if(tr[tr[k].l].ran<tr[tr[k].r].ran){
rorater(k);
del(k,x);
}
else{
roratel(k);
del(k,x);
}
}
}
else{
if(x>tr[k].key){
tr[k].sz--;
del(tr[k].r,x);
}
else{
tr[k].sz--;
del(tr[k].l,x);
}
}
}
int rank1(int k,int x){
if(k==0)
return 0;
if(tr[k].key==x){
return tr[tr[k].l].sz+1;
}
else{
if(x>tr[k].key)
return rank1(tr[k].r,x)+tr[k].re+tr[tr[k].l].sz;
else
return rank1(tr[k].l,x);
}
}
int rank2(int k,int x){
if(k==0)
return 0;
if(x<=tr[tr[k].l].sz){
return rank2(tr[k].l,x);
}
else if(x>(tr[tr[k].l].sz+tr[k].re))
return rank2(tr[k].r,x-tr[tr[k].l].sz-tr[k].re);
else
return tr[k].key;
}
void pre(int k,int x){
if(k==0)
return;
if(tr[k].key<x){
ans=k;
pre(tr[k].r,x);
}
else if(tr[k].key==x&&tr[k].re>1){
ans=k;
return;
}
else
pre(tr[k].l,x);
}
void beh(int k,int x){
if(k==0)
return;
if(tr[k].key>x){
ans=k;
beh(tr[k].l,x);
}
else if(tr[k].key==x&&tr[k].re>1){
ans=k;
return;
}
else
beh(tr[k].r,x);
}
//root1 - 2 root2 - 3
int main(){
// freopen("9.in","r",stdin);
// freopen("test.out","w",stdout);
srand(19260817);
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&back[i]),fir[i]=back[i];
for(int i=1;i<=n-1;i++){
insert(root1,abs(back[i]-back[i+1]));
insert(root2,back[i]);
}
// printf("%d %d\n",root1,root2);
insert(root2,back[n]);
insert(root2,0x3f3f3f3f);
insert(root2,-0x3f3f3f3f);
for(int i=1;i<=n;i++){
// printf("pre=%d beh=%d val=%d\n",pre(back[i],root2),beh(back[i],root2),back[i]);
beh(root2,back[i]);
int behans=tr[ans].key;
pre(root2,back[i]);
int preans=tr[ans].key;
min3=min(min3,min(abs(behans-back[i]),abs(preans-back[i])));
}
char opt[20];
for(int i=1;i<=m;i++){
scanf("%s",opt);
if(opt[0]=='I'){
int poi,addx;
scanf("%d %d",&poi,&addx);
insert(root2,addx);
beh(root2,addx);
int behans=tr[ans].key;
pre(root2,addx);
int preans=tr[ans].key;
min3=min(min3,min(abs(behans-addx),abs(preans-addx)));
del(root1,abs(fir[poi+1]-back[poi]));
insert(root1,abs(fir[poi+1]-addx));
insert(root1,abs(addx-back[poi]));
back[poi]=addx;
}
else{
if(opt[4]=='G'){
printf("%d\n",rank2(root1,1));
}
else
printf("%d\n",min3);
}
}
return 0;
}
FHQ-TREAP代码
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct Node{
int sz,w,ran,lson,rson;
}FHQ[501000<<2];
int Nodecnt,back[501000],root1,root2,min3=0x3f3f3f3f,fir[501000];
int newNode(int w){
++Nodecnt;
FHQ[Nodecnt].sz=1;
FHQ[Nodecnt].w=w;
FHQ[Nodecnt].ran=rand();
FHQ[Nodecnt].lson=FHQ[Nodecnt].rson=0;
return Nodecnt;
}
void pushup(int o){
FHQ[o].sz=FHQ[FHQ[o].lson].sz+FHQ[FHQ[o].rson].sz+1;
}
void split_val(int now,int k,int &x,int &y){
if(!now){
x=y=0;
return;
}
if(FHQ[now].w<=k){
x=now;
split_val(FHQ[now].rson,k,FHQ[now].rson,y);
}
else{
y=now;
split_val(FHQ[now].lson,k,x,FHQ[now].lson);
}
pushup(now);
}
int merge(int x,int y){//X.W < Y.W
if(!x||!y)
return x+y;
pushup(x);
pushup(y);
if(FHQ[x].ran<FHQ[y].ran){
FHQ[x].rson=merge(FHQ[x].rson,y);
pushup(x);
return x;
}
else{
FHQ[y].lson=merge(x,FHQ[y].lson);
pushup(y);
return y;
}
}
void insert(int x,int &root){
int mergeroot=newNode(x),a,b;
split_val(root,x,a,b);
root=merge(merge(a,mergeroot),b);
}
void erase(int x,int &root){
int a,b,c,d;
split_val(root,x,a,b);
split_val(a,x-1,c,d);
root=merge(merge(c,merge(FHQ[d].lson,FHQ[d].rson)),b);
}
int findkth(int now,int kth){
if(now==0)
return 0;
if(kth==FHQ[FHQ[now].lson].sz+1)
return now;
if(kth<=FHQ[FHQ[now].lson].sz)
return findkth(FHQ[now].lson,kth);
else
return findkth(FHQ[now].rson,kth-FHQ[FHQ[now].lson].sz-1);
}
int findrank(int &now,int wx){
int a,b;
split_val(now,wx-1,a,b);
int ans = FHQ[a].sz+1;
now=merge(a,b);
return ans;
}
int pre(int x,int &root){
int a,b;
split_val(root,x,a,b);
int ans=FHQ[findkth(a,FHQ[a].sz-1)].w;
root=merge(a,b);
return ans;
}
int beh(int x,int &root){
int a,b;
split_val(root,x-1,a,b);
int ans=FHQ[findkth(b,2)].w;
root=merge(a,b);
return ans;
}
//root1 - 2 root2 - 3
int main(){
// freopen("9.in","r",stdin);
// freopen("test.out","w",stdout);
srand(19260817);
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&back[i]),fir[i]=back[i];
for(int i=1;i<=n-1;i++){
insert(abs(back[i]-back[i+1]),root1);
insert(back[i],root2);
}
// printf("%d %d\n",root1,root2);
insert(back[n],root2);
insert(0x3f3f3f3f,root2);
insert(-0x3f3f3f3f,root2);
for(int i=1;i<=n;i++){
// printf("pre=%d beh=%d val=%d\n",pre(back[i],root2),beh(back[i],root2),back[i]);
min3=min(min3,min(abs(beh(back[i],root2)-back[i]),abs(pre(back[i],root2)-back[i])));
}
char opt[20];
for(int i=1;i<=m;i++){
scanf("%s",opt);
if(opt[0]=='I'){
int poi,addx;
scanf("%d %d",&poi,&addx);
insert(addx,root2);
min3=min(min3,min(abs(beh(addx,root2)-addx),abs(pre(addx,root2)-addx)));
erase(abs(fir[poi+1]-back[poi]),root1);
insert(abs(fir[poi+1]-addx),root1);
insert(abs(addx-back[poi]),root1);
back[poi]=addx;
}
else{
if(opt[4]=='G')
printf("%d\n",FHQ[findkth(root1,1)].w);
else
printf("%d\n",min3);
}
}
return 0;
}
p1110 报表统计(FHQ-TREAP/TREAP)的更多相关文章
- 【Luogu】P1110报表统计(Splay)
题目链接 SBT,我居然没看出来. 就是插入的时候考虑向平衡树里插两个差值,删一个差值. 另一个操作就是维护某元素和其前驱后继的差值最小值就行了. 然后Splay超时了…… (貌似Splay超时了之后 ...
- bzoj 1058: [ZJOI2007]报表统计 (Treap)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1058 题面; 1058: [ZJOI2007]报表统计 Time Limit: 15 Sec ...
- 洛谷 P1110 [ZJOI2007]报表统计 解题报告
P1110 [ZJOI2007]报表统计 题目描述 \(Q\)的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小\(Q\)希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细 ...
- [BZOJ1588][HNOI2002]营业额统计 无旋Treap
[HNOI2002]营业额统计 时间限制: 5 Sec 内存限制: 162 MB 题目描述 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以 ...
- bzoj1058: [ZJOI2007]报表统计
set.操作:insert(u,v)在u后面插入v,若u后面已插入过,在插入过的后面插入.mingap求出序列两两之间差值的最小值.minsortgap求出排序后的序列两两之间的最小值.用multis ...
- BZOJ 1058: [ZJOI2007]报表统计( 链表 + set )
这种题用数据结构怎么写都能AC吧...按1~N弄个链表然后每次插入时就更新答案, 用set维护就可以了... --------------------------------------------- ...
- [补档][ZJOI2007] 报表统计
[ZJOI2007] 报表统计 题目 传送门 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细观察,小Q发现统计一 ...
- 【BZOJ1058】【ZJOI2007】报表统计(链表,堆,Splay)
[BZOJ1058][ZJOI2007]报表统计 题面 题目描述 Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细观 ...
- BZOJ_1058_[ZJOI2007]报表统计_STL
BZOJ_1058_[ZJOI2007]报表统计_STL Description 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工 作,作为她的生日礼 ...
随机推荐
- 关于CTeX的几个大坑
https://blog.csdn.net/zjutczj/article/details/53463478 最近一直忙着写小论文,毕业设计中期答辩,没有更新博客,忙过这一阵我会把这段时间学习机器学习 ...
- 关于 redis、memcache、mongoDB 的对比 转
从以下几个维度,对 redis.memcache.mongoDB 做了对比.1.性能都比较高,性能对我们来说应该都不是瓶颈.总体来讲,TPS 方面 redis 和 memcache 差不多,要大于 m ...
- Java 内存分配
静态储存区:全局变量,static 内存在编译的时候就已经分配好了,并且这块内存在程序运行期间都存在. 栈储存区:1,局部变量.2,,保存类的实例,即堆区对象的引用.也可以用来保存加载方法时的帧.函数 ...
- 设计模式之Visitor(访问者)(转)
Visitor定义 作用于某个对象群中各个对象的操作. 它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作. 在Java中,Visitor模式实际上是分离了collection结构中的 ...
- JDK8 元空间
1. 运行时常量池和静态变量都存储到了堆中,MetaSpace存储类的元数据,MetaSpace直接申请在本地内存中(Native memory),这样类的元数据分配只受本地内存大小的限制,OOM问题 ...
- java == 与 equals 相同与不同点
java中与很多有意思又值得深究的点. 写这篇文章呢,是由于在百度知道中看到一个问题:怎样比较两个对象是否相同.这又使我想到了另外一个问题,== 和 equals有什么不同?写了几行代码,看了几篇文章 ...
- 关于setInterval的坑
一道面试题:“setInterval和setTimeout有什么区别” “如果setInterval计时器的回调函数执行完需要5秒,而计时器时间间隔为3秒,那会发生什么?” 验证代码 让程序滞留固定时 ...
- Zsh和oh my zsh的安装和使用
Zsh 兼容 Bash,据传说 99% 的 Bash 操作 和 Zsh 是相同的,默认 CentOS / Ubuntu / Mac 系统用的是 Bash,倒也不是说 Bash 不好,而是说我们有更好的 ...
- Linux:编译安装boost 1.69库
Boost库是为C++语言标准库提供扩展的一些C++程序库的总称,由Boost社区组织开发.维护.在C++的地位感觉可以和Spring在Java中相比. boost向来有准标准库之称,很多新特性例如智 ...
- 给web项目整合富文本编辑器
给jsp页面整合富文本编辑器下载——删除多余的组件——加入到项目中——参照案例来完成整合步骤:1. 解压zip文件,将所有文件复制到Tomcat的webapps/kindeditor目录下. 2. 将 ...