UVA - 1619 Feel Good(扫描法)

题目:

思路:

预处理出a[i]在哪个范围区间内是最小的,然后直接遍历a数组求答案就可以了。

这个预处理的技巧巧妙的用了之前的处理结果。(大佬tql)

代码:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1e3
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int maxn = 1000100;
int r[maxn],l[maxn];
ll sum[maxn],a[maxn];
int n;

int main(){
    FRE();
    int kase = 0;
    while(scanf("%d",&n)!=EOF){
        sum[0] = 0;
        a[0] = a[n+1] = -1;
        for(int i=1; i<=n; i++){
            scanf("%lld",&a[i]);
            sum[i] = sum[i-1]+a[i];
            l[i] = r[i] = i;
        }

        for(int i=1; i<=n; i++){//根据已经得到的范围快速求出当前的最小值范围
            while(a[i] <= a[l[i]-1]){
                l[i] = l[l[i]-1];
            }
        }

        for(int i=n; i>=1; i--){
            while(a[i] <= a[r[i]+1]){
                r[i] = r[r[i]+1];
            }
        }

        int L=1,R=1;//当不知道具体的边界的时候,就将边界设为开头
        ll ans = a[1]*a[1];
        for(int i=1; i<=n; i++){
            ll tsum = sum[r[i]] - sum[l[i]-1];
            if(ans < tsum * a[i]){
                L = l[i];
                R = r[i];
                ans = tsum*a[i];
            }
        }
        if(kase++){
            printf("\n");
        }
        printf("%lld\n",ans);
        printf("%d %d\n",L,R);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sykline/p/10352836.html