区间的价值

  从1到n分别假设每个数字为区间中的最小值。当假设a[i]为区间最小值时,区间最大值可能在左侧也可能在右侧,两种情况下处理的方式类似,这里只描述一下在左边时的情形。首先从a[i-1]开始向左边找到一个当a[i]为区间最小值时可以作为区间最大值的a[j],则应满足的条件为a[j]>a[i]且当j<k<i时,a[j]>=a[k]>=a[i]。然后从a[j-1]继续向左找到最小的下标l使得当l<=k<j时,a[j]>=a[k]>=a[i]。从a[i+1]向右找到最大的下标r使得当i<k<=r时,a[j]>=a[k]>=a[i]。区间左端点在[l,j],右端点在[i,r]的区间最大值和最小值均分别为a[j]和a[i],其长度最短为i-j+1,最长为r-l+1,以a[i]*a[j]的值更新相应的ans。重复此过程,直到找不到满足条件的j。

#include <stdio.h>
#include <string.h>
long long a[100005], ans[100005];
int main() {
    int n, l, r, j;
    long long max;
    while (scanf("%d", &n) != EOF) {
        for (int i = 1; i <= n; i++) {
            scanf("%lld", &a[i]);
        }
        memset(ans, 0, sizeof(ans));
        for (int i = 1; i <= n; i++) {
            j = r = i;
            max = a[i];
            while (j >= 1) {
                if (a[j] < max) {
                    break;
                }
                l = j;
                while (r + 1 <= n && a[i] <= a[r + 1] && a[r + 1] <= a[j]) {
                    r++;
                }
                while (l - 1 >= 1 && a[i] <= a[l - 1] && a[l - 1] <= a[j]) {
                    l--;
                }
                long long tmp = a[i] * a[j];
                for (int k = (i - j + 1); k <= (r - l + 1); k++) {
                    if (tmp > ans[k]) {
                        ans[k] = tmp;
                    }
                }
                max = a[j];
                j = l - 1;
            }
            j = l = i;
            max = a[i];
            while (j <= n) {
                if (a[j] < max) {
                    break;
                }
                r = j;
                while (l - 1 >= 1 && a[i] <= a[l - 1] && a[l - 1] <= a[j]) {
                    l--;
                }
                while (r + 1 <= n && a[i] <= a[r + 1] && a[r + 1] <= a[j]) {
                    r++;
                }
                long long tmp = a[i] * a[j];
                for (int k = (j - i + 1); k <= (r - l + 1); k++) {
                    if (tmp > ans[k]) {
                        ans[k] = tmp;
                    }
                }
                max = a[j];
                j = r + 1;
            }
        }
        for (int i = 1; i <= n; i++) {
            printf("%lld\n", ans[i]);
        }
    }
    return 0;
}
View Code

相关文章:

  • 2021-12-08
  • 2022-12-23
  • 2021-11-23
  • 2021-11-20
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-09-03
  • 2021-10-22
  • 2021-05-14
  • 2021-09-12
相关资源
相似解决方案