首页 > 其他分享 >P9991 [Ynoi Easy Round 2023] TEST_107 题解

P9991 [Ynoi Easy Round 2023] TEST_107 题解

时间:2023-12-29 16:22:05浏览次数:42  
标签:int 题解 线段 Ynoi cin 扫描线 P9991 inline void

思路

题目即要求删除区间中的一个或多个颜色。

考虑假如枚举删除颜色 \(k\)。

那么在 \(l,r\) 中的答案为:

\[\max_{i=1}^{m+1} a_i-a_{i-1} \]

其中 \(a_i\) 为颜色 \(k\) 在 \(l\sim r\) 中的出现位置,\(a_{0}=l,a_{m+1}=r\)。

可以分类讨论。

  1. 答案为 \(a_1-l\),那么只需要维护 \(l-r\) 中位置最小的 \(k\) 即可,对于所有颜色就是所有的位置的最大值,可以使用扫描线和线段树。

  2. 答案为 \(r-a_m\),那么只需要维护 \(l-r\) 中位置最大的 \(k\) 即可,对于所有颜色就是所有的位置的最小值,仍然可以使用扫描线和线段树。

  3. 答案为 \(a_i-a_{i-1}\),继续使用扫描线和线段树,每一次新加数时,在上一个位置记录此子区间的答案即可。

发现线段树只需要单点赋值,区间最值。

使用 zkw 线段树就非常方便啦。

Code

#include <bits/stdc++.h>
using namespace std;

#define fro(i, x, y) for(int i = (x);i <= (y);i++)
#define pre(i, x, y) for(int i = (x);i >= (y);i--)

const int N = 10000010;

int n, m, k, a[N], las[N];
int cnt, l[N], r[N], ans[N], head[N];
struct edge { int to, nxt; } e[N];
int t[N];

inline void upd(int x, int y)
{
	t[x += k] = y;
	for(x >>= 1; x; x >>= 1)
		t[x] = max(t[x<<1], t[x<<1|1]);
}
inline int ask(int l, int r)
{
	int res = -1e9;
	for(l += k - 1, r += k + 1; l ^ r ^ 1;)
	{
		if((l & 1) == 0) res = max(res, t[l ^ 1]);
		if((r & 1) == 1) res = max(res, t[r ^ 1]);
		l >>= 1, r >>= 1;
	}
	return res;
}
inline void fill() { memset(t, -0x3f, sizeof t), memset(las, 0, sizeof las); }
inline void ckmax(int &x, int y) { x = max(x, y); }
inline void add(int x, int y) { e[++cnt] = {y, head[x]}, head[x] = cnt; }

signed main()
{
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> n >> m, k = 1;
	fro(i, 1, n) cin >> a[i];
	fro(i, 1, m) cin >> l[i] >> r[i];
	while(k <= n + 1) k <<= 1;
	fro(i, 1, m) add(r[i], i);
	fill();
	fro(i, 1, n)
	{
		if(las[a[i]])
			upd(las[a[i]], i - las[a[i]] - 1);
		las[a[i]] = i;
		for(int j = head[i]; j; j = e[j].nxt)
			ckmax(ans[e[j].to], ask(l[e[j].to], r[e[j].to]));
	}
	fill();
	fro(i, 1, n)
	{
		if(las[a[i]]) upd(las[a[i]], -1e9);
		upd(i, -i), las[a[i]] = i;
		for(int j = head[i]; j; j = e[j].nxt)
			ckmax(ans[e[j].to], i + ask(l[e[j].to], r[e[j].to]));
	}
	fill();
	memset(head, 0, sizeof head), cnt = 0;
	fro(i, 1, m) add(l[i], i);
	pre(i, n, 1)
	{
		if(las[a[i]]) upd(las[a[i]], -1e9);
		upd(i, i), las[a[i]] = i;
		for(int j = head[i]; j; j = e[j].nxt)
			ckmax(ans[e[j].to], ask(l[e[j].to], r[e[j].to]) - i);
	}
	fro(i, 1, m) cout << ans[i] << "\n";
	return 0;
}

标签:int,题解,线段,Ynoi,cin,扫描线,P9991,inline,void
From: https://www.cnblogs.com/JiaY19/p/17935154.html

相关文章

  • AT_abc020_c 题解
    链接(atcoder)链接(luogu)简单算法组合(?算法一爆搜,时间复杂度\(O(2^{n\timesm}\timest)\),不能通过此题。算法二考虑二分\(t\),然后暴搜,时间复杂度\(O(2^{n\timesm}\timeslog2(t))\),不能通过此题。算法三考虑二分\(t\),然后暴记忆化搜索,时间复杂度\(O(n\timesm......
  • CF1234F 题解
    blog。小清新题,下文\(V=20\)即值域。反转操作,本质就是选两个不相交连续段拼起来。显然合法的最终串长度一定\(\leV\)。将这些合法串预处理出来,那么每个串都对应一个「字母集合」。随便DP一下,求出所有集合中,的最大的合法「字母集合」大小。\(dp_{\smallU}\)就是只选一......
  • CF1917F Construct Tree 题解
    题目链接:https://codeforces.com/contest/1917/problem/F题意有\(n\)条长度\(l_i\)的边,问它们是否能组成一棵\(n+1\)个节点的树,使得树的直径长度为\(d\)。\(n,d\le2000\)。题解首先当然要存在一个边集\(D\),使得\(\sum\limits_{i\inD}l_i=d\),这可以使用背包......
  • 在不使用内置函数和中间变量的情况交换数字LeetCode力扣题解面试题16.01
    #异或法#Kotlin```KotlinclassSolution{  funswapNumbers(numbers:IntArray):IntArray{    numbers[0]=numbers[0]xornumbers[1]    numbers[1]=numbers[1]xornumbers[0]    numbers[0]=numbers[0]xor......
  • AT_joisc2015_h 题解
    传送门题意:给定长为\(n\)的字符串\(s\),你可以选择一个区间,将区间内的字符从小到大排序,求可以得到的最长回文子串长度,字符集大小为\(n\)。很有意思的题目。首先容易做到\(O(n^3)\)。考虑怎么优化。我们先考察排序的区间和回文区间的关系。如果两个区间无交,那么显然排序......
  • CF1835C Twin Clusters 题解
    题目链接点击打开链接题目解法很牛逼的构造题好像随也可以过长度为\(2^{k+1}\)的序列的不同区间有\(2^{2k+1}\)个,值域是\(4^k\),所以一定有解将\(a\)做一遍前缀和,那么问题转化成了找\(s_{r1}\opluss_{l1-1}=s_{r2}\opluss_{l2-1}\)先讲一讲具体做法:按照前\(k\)......
  • ICPC2021Kunming G Glass Bead Game 题解
    QuestionICPC2021KunmingGGlassBeadGame有\(n\)个玻璃珠,\(B_1,B_2,\cdots,B_n\)每一步你可以选择一个\(B_i\)移道第一个位置上,花费的代价为操作前\(B_i\)前面的玻璃珠的个数。已知每一步选择玻璃珠\(B_i\)的概率\(p_i\),问当\(m\rightarrow\infty\)时,在第\(......
  • ICPC2021Kunming G Find the Maximum 题解
    QuestionFindtheMaximum给出一个树,每个点有一个权值\(b_n\),求一条树上路径\(V\),要求\(\frac{\sum_{u\inV(-x^2+b_ux)}}{|V|}\)最大,其中\(x\)是自己选择的一个树Solution先转化一下\(\frac{\sum_{u\inV(-x^2+b_ux)}}{|V|}\),得到\[\frac{\sum_{u\inV(-x^2+b_......
  • 洛谷 P9058 [Ynoi2004] rpmtdq
    洛谷传送门类比P9062[Ynoi2002]AdaptiveHsearch&Lsearch处理区间最近点对的思路,尝试只保留可能有贡献的点对。处理树上路径容易想到点分治。设点\(u\)到分治中心的距离为\(a_u\)。我们有\(\text{dis}(u,v)\lea_u+a_v\)。考虑一个点对\((u,v)\)什么时候一定没......
  • vue前端node内存溢出问题解决
    前端项目运行时,如果经常运行慢,崩溃停止服务,报如下错误:FATALERROR:CALL_AND_RETRY_LASTAllocationfailed-JavaScriptheapoutofmemory(JavaScript堆内存不足) 原因:因为在Node中,通过JavaScript使用内存时只能使用部分内存(64位系统:1.4GB,32位系统:0.7GB),这个时候,如......