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]报表统计的更多相关文章

  1. 洛谷.1110.[ZJOI2007]报表统计(Splay Heap)

    题目链接 附纯SplayTLE代码及主要思路: /* 可以看做序列有n段,Insert是每次在每一段最后插入一个元素 只有插入,没有删除,所以插入一个元素对于询问1影响的只有该元素与前边一个元素(同段 ...

  2. 洛谷.1110.[ZJOI2007]报表统计(Multiset Heap)

    题目链接 主要思路 /* 对于询问1,用堆代替multiset/Splay 对于询问2,multiset 1.注意哨兵元素 2.注意multiset中删除时是删除某元素的一个位置,而不是这个元素!这个 ...

  3. 洛谷.1110.[ZJOI2007]报表统计(Multiset)

    题目链接 主要思路 /* 其实只需要multiset即可 对于询问1,删除.插入差值,输出最小元素 对于询问2,插入后用前驱后继更新 1.注意哨兵元素 2.注意multiset中删除时是删除某元素的一 ...

  4. 洛谷 P1110 [ZJOI2007]报表统计 解题报告

    P1110 [ZJOI2007]报表统计 题目描述 \(Q\)的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小\(Q\)希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细 ...

  5. 2018.11.09 洛谷P1110 [ZJOI2007]报表统计(multiset)

    传送门 sb题. 直接用两个multisetmultisetmultiset维护相邻两个数的差值和所有数的前驱后继. 插入一个数的时候更新一下就行了. 代码: #include<bits/std ...

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

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

  7. bzoj1058: [ZJOI2007]报表统计

    set.操作:insert(u,v)在u后面插入v,若u后面已插入过,在插入过的后面插入.mingap求出序列两两之间差值的最小值.minsortgap求出排序后的序列两两之间的最小值.用multis ...

  8. 洛谷 P1169 [ZJOI2007]棋盘制作

    2016-05-31 14:56:17 题目链接: 洛谷 P1169 [ZJOI2007]棋盘制作 题目大意: 给定一块矩形,求出满足棋盘式黑白间隔的最大矩形大小和最大正方形大小 解法: 神犇王知昆的 ...

  9. BZOJ 1058: [ZJOI2007]报表统计( 链表 + set )

    这种题用数据结构怎么写都能AC吧...按1~N弄个链表然后每次插入时就更新答案, 用set维护就可以了... --------------------------------------------- ...

随机推荐

  1. BATCH、事务、CLOB、BLOB

    Batch:需要执行大量的数据时可以使用批处理 注意点: 1.尽量使用Statement,因为如果是PreParedStatement可能会因为数据量太大而存在空间问题,编译器会报错. 2.把自动提交 ...

  2. python学习(二)--数据类型

    数据类型 1.工厂函数 type() int() float() str() list() tuple() dict() bool() set()工厂函数的理解:工厂函数看上去有点像函数,实质上他们是 ...

  3. rest_famework 认证与权限组件

    定义个一个认证类 from rest_framework import exceptionsfrom rest_framework.authentication import BaseAuthenti ...

  4. 《用Python做HTTP接口测试》练习资料共享

    原作者代码在https://github.com/akuing/python-http-interface-test

  5. JeeWx全新版本发布!捷微二代微信活动平台1.0发布!活动插件持续开源更新!

    JeeWx捷微二代微信活动平台 (专业微信营销活动平台,活动插件持续更新ing~)    终于等到你!还好我没放弃! 在团队持续多年的努力下,Jeewx微信管家和H5活动平台不断更新迭代,积累了许许多 ...

  6. faiss索引基于数量级和内存限制的选择

    它是一个能使开发者快速搜索相似多媒体文件的算法库.而该领域一直是传统的搜索引擎的短板.借助Faiss,Facebook 在十亿级数据集上创建的最邻近搜索(nearest neighbor search ...

  7. Vue打包报错Unexpected token: punc(()解决方案

    (用vscode)vue项目打包时,报错,报错信息如下: ERROR in static/js/0.564c764efc3ecf31190c.js from UglifyJs Unexpected t ...

  8. jquery通过AJAX从后台获取信息并显示在表格上的类

    前一阵我写了:<jquery通过AJAX从后台获取信息并显示在表格上,并支持行选中.>现在,我把他们处理了一下,不需要每次写代码了: 具体代码如下: //获取数据并显示数据表格 funct ...

  9. Post提交带参网址

    前端 $(function(){ var obj=$('#form1'); obj.validate({ submitHandler: function (form){ var data={}; da ...

  10. LR基本知识学习

    性能测试基础 本质:基于 协议 模拟用户发请求,对服务器形成一定的负载,来测试服务器的性能指标是否满足要求,与界面无关 * 时间 * 空间 分类: 性能(狭义):特定条件下,验证  系统是否有宣称具有 ...