ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P7549 [BJWC2017] 神秘物质

2022-03-19 08:34:06  阅读:133  来源: 互联网

标签:P7549 神秘物质 10 int 最大值 极差 BJWC2017 最小值 区间


维护一个序列,要求支持合并相邻两个节点(并赋入新的值)、插入、询问一段区间中任意子区间的区间极差的最大值和最小值。

值域 \(10^9\),点数 \(10^5\),操作数 \(10^5\)。

std

算是一眼题了(那就水个题解)

对于修改,用平衡树维护即可。

对于极差最大值,显然用整段区间的最大值减最小值是最优的,维护子树内的最大值和最小值即可。

对于极差最小值,显然当子区间为 \(2\) 是答案最优,维护相邻两数的绝对值差即可。

所以,总时间复杂度为 \(\mathcal O(m \log n)\),可过。

#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;
}

标签:P7549,神秘物质,10,int,最大值,极差,BJWC2017,最小值,区间
来源: https://www.cnblogs.com/orzz/p/16025372.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有