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. python selenium 基本常用操作

    最近学习UI自动化,把一些常用的方法总结一下,方便自己以后查阅需要.因本人水平有限,有不对之处多多包涵!欢迎指正! 一.xpath模糊匹配定位元素 武林至尊,宝刀屠龙刀(xpath),倚天不出(css ...

  2. oo 第一次博客作业

    oo 第一次博客作业 早在大一就听说了oo的各种传奇故事,大二下学期终于也开始了我的oo之旅. 基于度量来分析自己的程序结构 第一次作业 类图分析 耦合度分析 可以看出在第一次作业中,我的耦合度非常高 ...

  3. jQuery入门基础(选择器)

    一.jQuery简介 jQuery 是一个 JavaScript 库. jQuery 极大地简化了 JavaScript 编程. jQuery 库位于一个 JavaScript 文件中,其中包含了所有 ...

  4. 分布式之redis核心知识盘点?

    考虑到绝大部分写业务的程序员,在实际开发中使用redis的时候,只会setvalue和getvalue两个操作,对redis整体缺乏一个认知.又恰逢博主某个同事下周要去培训redis,所以博主斗胆以r ...

  5. Git常用命令(一)

    转自2.1 Git 基础 - 获取 Git 仓库 获取帮助 `$ git help <verb> $ git <verb> --help $ man git-<verb& ...

  6. 监测c3动画过渡完成的事件

    监测css3动画完成的事件 transitionend 用法: let element = document.getElementById("slidingMenu"); elem ...

  7. js:一些基础

    JavaScript 基础(一)   JavaScript的引入方式 直接编写 <!DOCTYPE html> <html lang="en"> <h ...

  8. PuTTY窗口看不到鼠标解决方法

    PuTTY终端工具无法清晰看到鼠标如何处理?通常是因为PuTTY背景色和鼠标颜色相近导致.这里介绍一种通过调整鼠标状态解决方法.说明:文末附PuTTY最新版本下载地址. 操作步骤(Windows10) ...

  9. [PHP] 常备的现代 PHP 项目开发准备

    [ Windows 开发环境 ] phpStudy(http://phpstudy.php.cn/) 现在一般选择版本: php7.1 + nginx,常用 curl.openssl 扩展选择打开. ...

  10. java方法体

    执行顺序: 静态代码块 mian方法 构造代码块 构造方法 静态代码块只执行一次.