[BZOJ 1058] 报表统计
Link:
Solution:
为了这道题今天下午一直都在和常数大战……
1、对于询问1,我们记录每个数末位置的数$T[i]$和初始位置$S[i]$
用平衡树维护所有差值,对于操作$i,k$:删除$S[i+1]-T[i]$,增加$x-T[i]$和$x-S[i+1]$
2、对于询问2,用平衡树记录所有值,每次找到$k$的前驱和后继更新$mn$就好了
当然以上都可以不用手写平衡树,用$multiset$和$priority\_ queue$可水过
但我如此耿直的人还是用结构体写了两个$Splay$分别维护两个询问
下面总结下出的各种锅和常数优化细节吧:
1、补锅匠系列:
(1)范围要开到$2*n$,毕竟每次会新加进一个数
这时显示的居然是$TLE$不是$RE$?以后要注意……
(2)对于询问2在查找前驱后继时要包含与查找数相同的数
此时不是严格小于/大于啊……
2、卡常系列:
(1)基础的IO,$register$,$inline$
(2)进行任何操作后最好都$Splay$一遍来保证复杂度!
(3)如果$mn=0$时直接将后面的更新剪枝,好像对$Luogu$上的数据很有效……
(4)尽量少外界调用结构体内函数
卡常卡到最后还是只过了$Luogu$,$BZOJ$过不去啊……
但好像$BZOJ$数据加强了,黄学长的标程也T了……
最后发现别人用$Treap$写比我的快10倍?以后还是少写$Splay$吧
Code:
#include <bits/stdc++.h> using namespace std;//注意MAXN要开到1e6
const int MAXN=1e6+,INF=0x3f3f3f3f;
char s[];int n,m,dat[MAXN],S[MAXN],T[MAXN],mn=INF; inline int read()
{
char ch;int num,f=;
while(!isdigit(ch=getchar())) f|=(ch=='-');
num=ch-'';
while(isdigit(ch=getchar())) num=num*+ch-'';
return f?-num:num;
}
inline void write(int x)
{
if(x<) putchar('-'),x=-x;
if(x>) write(x/);
putchar(x%+'');
} struct splay
{
int rt,sz[MAXN],cnt[MAXN],val[MAXN],f[MAXN],ch[MAXN][],tot;
inline void pushup(int x)
{sz[x]=sz[ch[x][]]+sz[ch[x][]]+cnt[x];}
inline void Rotate(int x)
{
int y=f[x],z=f[y],k=(ch[y][]==x);
ch[z][ch[z][]==y]=x;f[x]=z;
ch[y][k]=ch[x][k^];f[ch[x][k^]]=y;
ch[x][k^]=y;f[y]=x;
pushup(x);pushup(y);
}
inline void Splay(int x,int up)
{
while(f[x]!=up)
{
int y=f[x],z=f[y];
if(z!=up) (ch[y][]==x)^(ch[z][]==y)?Rotate(x):Rotate(y);
Rotate(x);
}
if(!up) rt=x;
}
inline void Insert(int x)
{
int k=rt,anc=;
while(k&&x!=val[k])
anc=k,k=ch[k][x>val[k]]; if(k) {cnt[k]++;Splay(k,);return;}
k=++tot;
if(anc) ch[anc][x>val[anc]]=k;
ch[k][]=ch[k][]=;
sz[k]=cnt[k]=;f[k]=anc;val[k]=x;
Splay(k,);
}
inline void Find(int x)
{
int k=rt;
while(ch[k][x>val[k]]&&x!=val[k])
k=ch[k][x>val[k]];
Splay(k,);
}
inline int Kth(int x)
{
int k=rt;
while(true)
{
if(sz[ch[k][]]+cnt[k]<x)
x-=sz[ch[k][]]+cnt[k],k=ch[k][];
else if(sz[ch[k][]]>=x) k=ch[k][];
else return k;
}
}
inline int Next(int x,int flag)
{
Find(x);int k=rt;
if((val[k]<x&&!flag)||(val[k]>x&&flag)) return k;
k=ch[k][flag];
while(ch[k][flag^]) k=ch[k][flag^];
Splay(k,);return k;
}
inline int Next2(int x,int flag)
{
Find(x);int k=rt;
if((val[k]<=x&&!flag)||(val[k]>=x&&flag)) return k;
k=ch[k][flag];
while(ch[k][flag^]) k=ch[k][flag^];
Splay(k,);return k;
}
inline void Delete(int x)
{
int nxt=Next(x,),lst=Next(x,);
Splay(lst,);Splay(nxt,lst);
if(cnt[ch[nxt][]]>)
cnt[ch[nxt][]]--,Splay(ch[nxt][],);
else ch[nxt][]=;
}
inline void push(int x)
{//调用结构体函数的次数越少越好,因此push放里面快
if(!mn) return;
int nxt=Next2(x,),lst=Next2(x,);
mn=min(mn,min(abs(val[nxt]-x),abs(val[lst]-x)));
Insert(x);
}
}all,adj; int main()
{
n=read();m=read();
all.Insert(INF);all.Insert(-INF);
adj.Insert(INF);adj.Insert(-INF);
for(register int i=;i<=n;i++)
dat[i]=read(),all.push(dat[i]),S[i]=T[i]=dat[i];
for(register int i=;i<=n;i++) adj.Insert(abs(dat[i]-dat[i-])); while(m--)
{
int x,y;scanf("%s",s);
if(s[]=='I')
{
x=read();y=read();
if(x!=n) adj.Delete(abs(S[x+]-T[x]));
adj.Insert(abs(y-T[x]));
adj.Insert(abs(y-S[x+]));
all.push(y);T[x]=y;
}
else if(s[]=='G') write(adj.val[adj.Kth()]),putchar('\n');
else write(mn),putchar('\n');
}
return ;
}
[BZOJ 1058] 报表统计的更多相关文章
- BZOJ 1058 报表统计 (STL)
题解:数据结构的基本操作,用STL可以完美实现,就是比较慢…… #include <cstdio> #include <map> #include <set> #i ...
- BZOJ 1058: [ZJOI2007]报表统计( 链表 + set )
这种题用数据结构怎么写都能AC吧...按1~N弄个链表然后每次插入时就更新答案, 用set维护就可以了... --------------------------------------------- ...
- bzoj 1058: [ZJOI2007]报表统计 (Treap)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1058 题面; 1058: [ZJOI2007]报表统计 Time Limit: 15 Sec ...
- [BZOJ 1058] [ZJOI2007] 报表统计 【平衡树】
题目链接:BZOJ - 1058 题目分析 这道题看似是需要在序列中插入一些数字,但其实询问的内容只与相邻的元素有关. 那么我们只要对每个位置维护两个数 Ai, Bi, Ai 就是初始序列中 i 这个 ...
- bzoj P1058 [ZJOI2007]报表统计——solution
1058: [ZJOI2007]报表统计 Time Limit: 15 Sec Memory Limit: 162 MB Submit: 4099 Solved: 1390 [Submit][St ...
- bzoj1058: [ZJOI2007]报表统计
set.操作:insert(u,v)在u后面插入v,若u后面已插入过,在插入过的后面插入.mingap求出序列两两之间差值的最小值.minsortgap求出排序后的序列两两之间的最小值.用multis ...
- [补档][ZJOI2007] 报表统计
[ZJOI2007] 报表统计 题目 传送门 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细观察,小Q发现统计一 ...
- 【BZOJ1058】【ZJOI2007】报表统计(链表,堆,Splay)
[BZOJ1058][ZJOI2007]报表统计 题面 题目描述 Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细观 ...
- BZOJ_1058_[ZJOI2007]报表统计_STL
BZOJ_1058_[ZJOI2007]报表统计_STL Description 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工 作,作为她的生日礼 ...
随机推荐
- 【BZOJ】1385 [Baltic2000]Division expression
[算法]欧几里德算法 [题解]紫书原题 #include<cstdio> #include<algorithm> using namespace std; ; int T,t, ...
- for in、each; for 、forEach、map
1.jQuery.each(object, [callback]) 用于例遍任何对象.回调函数拥有两个参数:第一个为对象的成员或数组的索引,第二个为对应变量或内容.如果需要退出 each 循环可使回调 ...
- node启动服务
npm install http-server -g http-server ipconfig查看当前ip 手机可访问第一个网址.
- Python3安装Celery模块后执行Celery命令报错
1 Python3安装Celery模块后执行Celery命令报错 pip3 install celery # 安装正常,但是执行celery 命令的时候提示没有_ssl模块什么的 手动在Python解 ...
- Python3 嵌套函数
嵌套函数: 函数体内用def定义函数 注意:函数体中调用其他函数不算嵌套函数,只能是函数的调用 简单的嵌套函数: 输出结果:
- Caffe学习笔记4图像特征进行可视化
Caffe学习笔记4图像特征进行可视化 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit201 ...
- Linux 入门记录:十七、Linux 命令行文本/文件处理工具
一.文件浏览 cat 查看文件内容 more 以翻页形式查看文件内容(只能向下翻页) less 以翻页形式查看文件内容(可以上下翻页) head 查看文件的头几行(默认10行) tail 查看文件的尾 ...
- c++设计模式系列----factory模式
问题: 假设我们要开发一个游戏--打怪物,首先,游戏有分等级,假设有初级,中级两个个等级(就不用flappy bird模式了,那个比较特殊,对一个玩家来说是难以具有持久吸引力的!),不同的等级怪物也是 ...
- mac 使用清除废纸篓或彻底删除某文件 附加: smb afp ftp NAS 访问服务器相关
mac 使用清除废纸篓或彻底删除某文件 附加: smb afp ftp NAS 访问服务器相关 mac 下删除文件方法: 1.使用 cleanmymac 使用 cleamymac 的清理 和 逐个 ...
- django “如何”系列6:如何部署django
django满满的快捷方法是的web开发者活的更轻松,但是,如果你不能部署你的站点的话,这是一点用都没有的.不违初衷,部署的简化也是django的一大目标.你可以有几个方法轻松的部署django 由于 ...