BZOJ1058或洛谷1110 [ZJOI2007]报表统计
BZOJ原题链接
洛谷原题链接
STL
本题可以直接使用\(\mathtt{STL\ multiset}\)水过去。
因为本题插入数的操作实际上就是将原数列分为\(n\)段,在每一段的末尾插入数,所以我们只需维护每一段的开头和末尾两个数,这样更新相邻差值时只需考虑插入数与原末尾和下一段的开头两个数的差值就好。
而维护这个差值,只开一个\(\mathtt{multiset}\)就好(其中是所有相邻差值)。当插入一个数时,先将原本的末尾和后一段开头的差值从\(\mathtt{multiset}\)里删除,再插入新的差值即可。
而所有元素中最接近的两个元素的差值,实际上就是找每个数的前驱和后继,再作差取最小值。
同样开个\(\mathtt{multiset}\)来维护(其中是所有元素),当插入数时,找其前驱和后继作差取\(\min\)即可。
#include<cstdio>
#include<set>
using namespace std;
const int N = 5e5 + 10;
multiset<int> S, D;
int st[N], ed[N], mi = 1e9, n, l;
char C[20];
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
inline void re_l()
{
char c = getchar();
for (l = 0; (c < 'A' || c > 'Z') && c != '_'; c = getchar());
for (; (c >= 'A' && c <= 'Z') || c == '_'; c = getchar())
C[l++] = c;
}
inline int jd(int x) { return x < 0 ? -x : x; }
inline int minn(int x, int y) { return x < y ? x : y; }
inline void update_S(int x)
{
multiset<int>::iterator it = S.lower_bound(x), k = it;
mi = minn(mi, minn(jd(x - *it), jd(x - *(--k))));
S.insert(x);
}
inline void update_D(int x, int y)
{
if (x ^ n)
D.erase(D.find(jd(st[x + 1] - ed[x]))), D.insert(jd(st[x + 1] - y));
D.insert(jd(y - ed[x]));
ed[x] = y;
}
int main()
{
int i, m, x, y;
n = re(); m = re();
S.insert(-1e9); S.insert(1e9);
for (i = 1; i <= n; i++)
update_S(st[i] = ed[i] = re());
for (i = 2; i <= n; i++)
D.insert(jd(st[i] - ed[i - 1]));
for (i = 1; i <= m; i++)
{
re_l();
if (C[0] == 'I')
{
x = re(); y = re();
update_S(y); update_D(x, y);
}
else
if (C[4] == 'S')
printf("%d\n", mi);
else
printf("%d\n", *D.begin());
}
return 0;
}
平衡树+线段树/堆/……
若不用\(\mathtt{STL}\),只需将其中一个\(\mathtt{multiset}\)改为平衡树,另一个改为线段树/堆之类的维护最小值的数据结构即可。
这里我用的是\(\mathtt{Splay}\)和线段树。
平衡树同样是插入所有元素,找前驱后继作差取最小值。
而线段树是插入每一段的末尾与其下一段的开头的差,维护一个最小值,而段内的相邻差值则再开一个变量维护最小值,对该询问的答案就是这两个取\(\min\)。
#include<cstdio>
using namespace std;
const int N = 5e5 + 10;
struct sp {
int so[2], fa, v;
};
sp tr[N << 1];
int MI[N << 2], st[N], ed[N], ro, SP, l;
char C[20];
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
inline void re_l()
{
char c = getchar();
for (l = 0; (c < 'A' || c > 'Z') && c != '_'; c = getchar());
for (; (c >= 'A' && c <= 'Z') || c == '_'; c = getchar())
C[l++] = c;
}
inline int jd(int x) { return x < 0 ? -x : x; }
inline int minn(int x, int y) { return x < y ? x : y; }
inline int maxn(int x, int y) { return x > y ? x : y; }
inline int who(int x) { return tr[tr[x].fa].so[0] ^ x ? 1 : 0; }
inline void ch(int x, int fa, int lr) { tr[fa].so[lr] = x; tr[x].fa = fa; }
inline void rtt(int x)
{
int y = tr[x].fa, r = tr[y].fa, soy = who(x), sor = who(y);
ch(tr[x].so[soy ^ 1], y, soy);
ch(y, x, soy ^ 1); ch(x, r, sor);
}
void sy(int x, int y)
{
int z = tr[x].fa;
if (!(ro ^ y))
ro = x;
y = tr[y].fa;
for (; tr[x].fa ^ y; z = tr[x].fa)
if (!(tr[z].fa ^ y))
rtt(x);
else
{
who(x) ^ who(z) ? rtt(x) : rtt(z);
rtt(x);
}
}
inline int newnode(int x, int fa)
{
tr[++SP].fa = fa;
tr[SP].v = x;
return SP;
}
void ins(int x)
{
if (!ro)
ro = newnode(x, 0);
else
for (int y, k = ro; ; k = tr[k].so[y])
{
if (!(tr[k].v ^ x))
return;
if (!tr[k].so[y = x < tr[k].v ? 0 : 1])
{
int nw = newnode(x, k);
tr[k].so[y] = nw; sy(nw, ro);
return;
}
}
}
inline int qu_pre(int x)
{
int s = -1e9;
for (int k = ro; k; k = tr[k].so[x <= tr[k].v ? 0 : 1])
if (x >= tr[k].v)
s = maxn(s, tr[k].v);
return s;
}
inline int qu_suc(int x)
{
int s = 1e9;
for (int k = ro; k; k = tr[k].so[x >= tr[k].v ? 1 : 0])
if (x <= tr[k].v)
s = minn(s, tr[k].v);
return s;
}
void pp(int r) { MI[r] = minn(MI[r << 1], MI[r << 1 | 1]); }
void bu(int r, int x, int y)
{
if (!(x ^ y))
MI[r] = jd(st[x] - st[x - 1]);
else
{
int mid = (x + y) >> 1;
bu(r << 1, x, mid);
bu(r << 1 | 1, mid + 1, y);
pp(r);
}
}
void upd(int r, int x, int y, int q, int k)
{
if (!(x ^ y))
MI[r] = k;
else
{
int mid = (x + y) >> 1;
q <= mid ? upd(r << 1, x, mid, q, k) : upd(r << 1 | 1, mid + 1, y, q, k);
pp(r);
}
}
int main()
{
int i, n, m, x, y, mi = 1e9, mis = 1e9;
n = re(); m = re();
st[0] = st[n + 1] = 1e9;
for (i = 1; i <= n; i++)
{
st[i] = ed[i] = re();
if (i ^ 1)
mis = minn(mis, minn(jd(qu_pre(st[i]) - st[i]), jd(qu_suc(st[i]) - st[i])));
ins(st[i]);
}
bu(1, 1, n);
for (i = 1; i <= m; i++)
{
re_l();
if (C[0] == 'I')
{
x = re(); y = re();
mis = minn(mis, minn(jd(qu_pre(y) - y), jd(qu_suc(y) - y)));
ins(y);
mi = minn(mi, jd(y - ed[x]));
upd(1, 1, n, x, jd(st[x + 1] - y));
ed[x] = y;
}
else
if (C[4] == 'S')
printf("%d\n", mis);
else
printf("%d\n", minn(mi, MI[1]));
}
return 0;
}
BZOJ1058或洛谷1110 [ZJOI2007]报表统计的更多相关文章
- 洛谷.1110.[ZJOI2007]报表统计(Splay Heap)
题目链接 附纯SplayTLE代码及主要思路: /* 可以看做序列有n段,Insert是每次在每一段最后插入一个元素 只有插入,没有删除,所以插入一个元素对于询问1影响的只有该元素与前边一个元素(同段 ...
- 洛谷.1110.[ZJOI2007]报表统计(Multiset Heap)
题目链接 主要思路 /* 对于询问1,用堆代替multiset/Splay 对于询问2,multiset 1.注意哨兵元素 2.注意multiset中删除时是删除某元素的一个位置,而不是这个元素!这个 ...
- 洛谷.1110.[ZJOI2007]报表统计(Multiset)
题目链接 主要思路 /* 其实只需要multiset即可 对于询问1,删除.插入差值,输出最小元素 对于询问2,插入后用前驱后继更新 1.注意哨兵元素 2.注意multiset中删除时是删除某元素的一 ...
- 洛谷 P1110 [ZJOI2007]报表统计 解题报告
P1110 [ZJOI2007]报表统计 题目描述 \(Q\)的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小\(Q\)希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细 ...
- 2018.11.09 洛谷P1110 [ZJOI2007]报表统计(multiset)
传送门 sb题. 直接用两个multisetmultisetmultiset维护相邻两个数的差值和所有数的前驱后继. 插入一个数的时候更新一下就行了. 代码: #include<bits/std ...
- 【BZOJ1058】[ZJOI2007]报表统计 STL
[BZOJ1058][ZJOI2007]报表统计 Description 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一.经 ...
- bzoj1058: [ZJOI2007]报表统计
set.操作:insert(u,v)在u后面插入v,若u后面已插入过,在插入过的后面插入.mingap求出序列两两之间差值的最小值.minsortgap求出排序后的序列两两之间的最小值.用multis ...
- 洛谷 P1169 [ZJOI2007]棋盘制作
2016-05-31 14:56:17 题目链接: 洛谷 P1169 [ZJOI2007]棋盘制作 题目大意: 给定一块矩形,求出满足棋盘式黑白间隔的最大矩形大小和最大正方形大小 解法: 神犇王知昆的 ...
- BZOJ 1058: [ZJOI2007]报表统计( 链表 + set )
这种题用数据结构怎么写都能AC吧...按1~N弄个链表然后每次插入时就更新答案, 用set维护就可以了... --------------------------------------------- ...
随机推荐
- 基于vue和svg的树形UI
vue-svg-tree 基于vue和svg的动态树形UI 截图 应用 npm install vue-svg-tree 示例 <template> <div> <v ...
- 如何解决iOS界面操作导致导致NSTimer暂停计时的问题?
在NSTimer代码后面加上以下代码,这样滚动scroll的时候就不会暂停了.NSRunLoop *t = [NSRunLoop currentRunLoop];[t addTimer: timer ...
- Spring Boot微服务如何集成fescar解决分布式事务问题?
什么是fescar? 关于fescar的详细介绍,请参阅fescar wiki. 传统的2PC提交协议,会持有一个全局性的锁,所有局部事务预提交成功后一起提交,或有一个局部事务预提交失败后一起回滚,最 ...
- python———day01
一.变量命名规则: 1,要有描述性: 2,变量名只能以 下划线,数字,字母组成,不可以有特殊符号和空格: 3,不能以中文为变量名(规范): 4,不能以数字开头: 5,保留字符(即关键字:如print ...
- ActiveMQ(4)---ActiveMQ原理分析之消息消费
消费端消费消息的原理 我们通过上一节课的讲解,知道有两种方法可以接收消息,一种是使用同步阻塞的MessageConsumer#receive方法.另一种是使用消息监听器MessageListener. ...
- Monkey测试简介
1.Monkey测试简介monkey是安卓命令行工具,它向系统发送伪随机的用户事件,例如:按键的输入.触摸屏的输入.手势输入等操作来对设备上的程序进行压力测试,检测程序多久的时间会发生异常.因此,mo ...
- 基于SSM的CRUD项目的详解
创一个maven工程 创建web的目录和web.xml------------右击项目,build projet--->configure project---->Project fac ...
- 如何才能成为一个合格的web前端工程师
转载原文地址:https://juejin.im/post/5cc1da82f265da036023b628 开篇前端开发是一个非常特殊的行业,它的历史实际上不是很长,但是知识之繁杂,技术迭代速度之快 ...
- 深度原理与框架-图像超分辨重构-tensorlayer
图像超分辨重构的原理,输入一张像素点少,像素较低的图像, 输出一张像素点多,像素较高的图像 而在作者的文章中,作者使用downsample_up, 使用imresize(img, []) 将图像的像素 ...
- web跨域问题(No 'Access-Control-Allow-Origin'..)
1. 问题 angular开发中连接java服务时出现跨域问题(No 'Access-Control-Allow-Origin'..). 如下图 解决方法 2,原因分析 这个与安全机制有关,默认情况下 ...