『环形处理』环路运输

题目描述

在这里插入图片描述

题解

一个非常显然的结论,如果我们要计算i-j(i<j)的答案:

  • 如果 i j &gt; n 2 i-j&gt;\frac{n}{2} ,一定选择 n ( i j ) = j + n i . n-(i-j)=j+n-i. 此时 ( j + n ) i &lt; n 2 (j+n)-i&lt;\frac{n}{2} .此时相当于求解 j + n j+n i i 的答案.
  • 否则,选择 i j . i-j.

此时,我们可以将区间扩大一倍,求解距离为 n 2 \frac{n}{2} 内的, a [ j ] j a[j]-j 值最大的点。

此时我们可以用优先队列来维护,还是很简单的。’

因此在解决环形问题的时候,我们还可以考虑扩大一倍的方法来解决问题。

代码如下:

#include <bits/stdc++.h> 

using namespace std;
const int N = 2000000;

int n, h = 1, t = 0, ans = 0;
int a[N], q[N];

inline int read(void)
{
    int s = 0, w = 1; char c = getchar();
    while (c < '0' || c > '9') c = getchar();
    while (c >= '0' && c <= '9') s = s*10+c-48, c = getchar();
    return s * w;
} 

int main(void)
{
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
	n = read();
	for (int i=1;i<=n;++i) a[i] = a[i+n] = read();
	for (int i=1;i<=n*2;++i)
	{
		while (h <= t && i-q[h] > n/2) h ++;
		ans = max(ans,a[i]+i+a[q[h]]-q[h]);
		while (h <= t && a[i]-i >= a[q[t]]-q[t]) t --;//注意维护a[i]-i的最小值 
		q[++t] = i; 
	}
	cout << ans <<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Ronaldo7_ZYB/article/details/92642637