P7549 [BJWC2017] 神秘物质
维护一个序列,要求支持合并相邻两个节点(并赋入新的值)、插入、询问一段区间中任意子区间的区间极差的最大值和最小值。
值域 ,点数 ,操作数 。
std
算是一眼题了~~(那就水个题解)~~。
对于修改,用平衡树维护即可。
对于极差最大值,显然用整段区间的最大值减最小值是最优的,维护子树内的最大值和最小值即可。
对于极差最小值,显然当子区间为 是答案最优,维护相邻两数的绝对值差即可。
所以,总时间复杂度为 ,可过。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int _ = 1e6 + 10;
inline int read()
{
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
x = x * 10 + (c - '0'), c = getchar();
return x * f;
}
int n, m, root, cnt;
struct Tree
{
int l, r, key, val, siz, mx, mn, les, res, mires;
} tr[_];
void update(int k)
{
tr[k].siz = tr[tr[k].l].siz + tr[tr[k].r].siz + 1;
tr[k].mx = tr[k].mn = tr[k].les = tr[k].res = tr[k].val;
tr[k].mires = 2e9;
if (tr[k].l != 0)
tr[k].mx = max(tr[k].mx, tr[tr[k].l].mx),
tr[k].mn = min(tr[k].mn, tr[tr[k].l].mn),
tr[k].les = tr[tr[k].l].les,
tr[k].mires = min(tr[k].mires, min(abs(tr[tr[k].l].res - tr[k].val), tr[tr[k].l].mires));
if (tr[k].r != 0)
tr[k].mx = max(tr[k].mx, tr[tr[k].r].mx),
tr[k].mn = min(tr[k].mn, tr[tr[k].r].mn),
tr[k].res = tr[tr[k].r].res,
tr[k].mires = min(tr[k].mires, min(abs(tr[tr[k].r].les - tr[k].val), tr[tr[k].r].mires));
}
int New(int v)
{
int now = ++cnt;
tr[now].val = tr[now].mx = tr[now].mn = tr[now].les = tr[now].res = v;
tr[now].mires = 2e9;
tr[now].siz = 1;
tr[now].key = rand();
return now;
}
void put(int i)
{
if (tr[i].l)
put(tr[i].l);
printf("%d ", tr[i].val);
if (tr[i].r)
put(tr[i].r);
}
void split(int rt, int val, int &x, int &y)
{
if (!rt)
{
x = y = 0;
return;
}
if (tr[tr[rt].l].siz < val)
{
x = rt;
split(tr[rt].r, val - tr[tr[rt].l].siz - 1, tr[rt].r, y);
}
else
{
y = rt;
split(tr[rt].l, val, x, tr[rt].l);
}
update(rt);
}
int merge(int x, int y)
{
if (!x || !y)
return x + y;
if (tr[x].key < tr[y].key)
{
tr[x].r = merge(tr[x].r, y);
update(x);
return x;
}
else
{
tr[y].l = merge(x, tr[y].l);
update(y);
return y;
}
}
void insert(int pos, int val)
{
int x, y;
split(root, pos, x, y);
root = merge(merge(x, New(val)), y);
}
int query1(int l, int r)
{
int x, y, z, res;
split(root, r, y, x);
split(y, l - 1, z, y);
res = tr[y].mx - tr[y].mn;
root = merge(merge(z, y), x);
return res;
}
int query2(int l, int r)
{
int x, y, z, res;
split(root, r, y, x);
split(y, l - 1, z, y);
res = tr[y].mires;
root = merge(merge(z, y), x);
return res;
}
signed main()
{
srand(time(0));
n = read(), m = read();
for (int i = 1; i <= n; ++i)
{
insert(i - 1, read());
}
char op[107];
int a, b;
while (m--)
{
scanf("%s", op);
a = read(), b = read();
if (op[1] == 'e')
{
int x, y, z;
split(root, a + 1, x, y), split(x, a - 1, x, z);
root = merge(merge(x, New(b)), y);
}
else if (op[1] == 'n')
{
insert(a, b);
}
else if (op[1] == 'a')
{
printf("%lld\n", query1(a, b));
}
else if (op[1] == 'i')
{
printf("%lld\n", query2(a, b));
}
}
return 0;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18122020
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!