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维护就可以了... --------------------------------------------- ...
随机推荐
- 小程序[publib]:1 request:fail ssl hand shake error 如果用的是阿里云和宝塔那么如下解决
小程序[publib]:1 request:fail ssl hand shake error 如果用的是阿里云和宝塔那么如下解决 宝塔里面的站点SSL右侧的配置(PEM格式) 需要把 阿里云 下载的 ...
- python目录结构
import sys,os #__file__取得当前文件名,pycharm会自动加上完整路径 #os.path.dirname取得上一级目录 #os.path.abspath取得绝对路径 BASE_ ...
- 【jira】java.lang.OutOfMemoryError: GC overhead limit exceeded
登录JIRA访问打开缓慢,查询日志出现下述提示:java.lang.OutOfMemoryError: GC overhead limit exceeded 修改setenv.sh文件中的JVM配置, ...
- 10Linux_firewalld-Linux就该这么学
firewalld: runtime:当前生效,重启后失效(默认) permanent:当前不生效,重启后永久生效. A:重启,B:执行firewall-cmd --reload 数据链路层:ipta ...
- 回溯法 17. Letter Combinations of a Phone Number
class Solution { public: map<char,string> dict; vector<string> letterCombinations(string ...
- linux7 安装 zlib依赖库 与安装python 3.6
Linux 安装zlib依赖库 进入src: cd /usr/local/src 下载zlib库: wget http://www.zlib.net/zlib-1.2.11.tar.gz 解压下载的t ...
- C 语言 字符串命令 strstr()的用法 实现将原字符串以分割串分割输出
C 语言 字符串命令 strstr()的用法 实现将原字符串以分割串分割输出 strstr() 命令是在原字符串中查找指定的字符串第一次出现的地址,用这个特性可以实现字符的分割,判断是否包涵等功能: ...
- springboot项目创建
1.在eclipse中创建springboot项目,右键找到New,然后找到Spring Starter Project, 如果menu中找不到Spring Starter Project就选择oth ...
- position:fixed失效情况
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- hbase-hive整合及sqoop的安装配置使用
从hbase中拿数据,然后整合到hbase中 上hive官网 -- 点击wiki--> hive hbase integation(整合) --> 注意整合的时候两个软件的版本要能进行整 ...