【Codeforces】Codeforces Round #839 (Div. 3) D. Absolute Sorting | 区间交

175 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第24天,点击查看活动详情

题目链接

Codeforces Round #839 (Div. 3)

题目

image.png

题目大意

给定一个由 nn 个整数组成的数组 aa。如果 a1a2ana_1≤a_2≤……≤a_n,则说明该数组是有序的。

这道题要求通过恰好应用一次以下操作,使数组被操作后是有序的:

  • 选择一个整数 xx,然后对于每个 i[1n]i∈[1,n],用 aix|a_i−x| 替换 aia_i

输出任何合法的 xx 值,无解输出 -1

思路

我们首先观察给定的数组,如果给定的数组仅包含两个元素,那么有

  • 如果 a1>=a2a_1>=a_2,合法的 xx 的范围是 [0,a1+a22][0,\lfloor\frac{a_1 + a_2}{2}\rfloor]
  • 如果 a1<=a2a_1<=a_2,合法的 xx 的范围是 [a1+a22,109][\lceil\frac{a_1 + a_2}{2}\rceil,10^9]

n>2n>2 时,每相邻两个元素都可以通过上述方式确定使得修改后的 ai1aia_{i-1}\le a_ixx 的范围:

  • 如果 ai1>=aia_{i-1}>=a_i,合法的 xx 的范围是 [0,ai1+ai2][0,\lfloor\frac{a_{i-1} + a_{i}}{2}\rfloor]
  • 如果 ai1<=aia_{i-1}<=a_i,合法的 xx 的范围是 [ai1+ai2,109][\lceil\frac{a_{i-1} + a_i}{2}\rceil,10^9]

因为当 ab,bca\le b,b\le c 时,有 abca\le b\le c,所以每相邻两个元素都保证了 ai1aia_{i-1}\le a_i,整个数组就是有序的。根据上述规则我们可以求得 n1n-1 个区间,这 nn 个区间内取交集,公共部分就是能使得整个数组变成有序的 xx 的取值。

如果交集为空则无解,输出 -1

代码

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <math.h>
#include <map>
#include <queue>
#include <vector>
#include <stdlib.h>
#include <time.h>
#include <set>
using namespace std;
using LL=long long;
const int N=1e6+5;
//const LL mod=998244353;
const LL mod=1e9+7;
int n,m,k;
int a[N];
LL solve()
{
	int flag=0,u=1e9,d=0;
	scanf("%d",&n);
	scanf("%d",&a[1]);
	for (int i=2;i<=n;++i)
	{
		scanf("%d",&a[i]);
		if (a[i]>a[i-1]) u=min(u,(a[i]+a[i-1])/2);
		if (a[i]<a[i-1]) d=max(d,(a[i]+a[i-1]+1)/2);
	}
	if (u>=d) printf("%d\n",u);
	else printf("-1\n");
	return 0;
}
int main()
{
	int T=1;
	scanf("%d",&T);

	while (T--) solve();

//	while (T--)
//		if (solve()) printf("Yes\n");
//		else printf("No\n");

//	while (T--) printf("%lld\n",solve());
	return 0;
}