zoukankan      html  css  js  c++  java
  • UVA

    题目:

    思路:

    预处理出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("
    ");
            }
            printf("%lld
    ",ans);
            printf("%d %d
    ",L,R);
        }
        return 0;
    }
  • 相关阅读:
    SP503 【PRINT
    UVA10924 【Prime Words】
    UVA902 【Password Search】
    UVA10339 【Watching Watches】
    UVA11057 【Exact Sum】
    DP题单解题报告合集
    P1829 [国家集训队]Crash的数字表格 / JZPTAB
    莫比乌斯反演入门
    莫比乌斯函数
    题解 P3168 [CQOI2015]任务查询系统
  • 原文地址:https://www.cnblogs.com/sykline/p/10352836.html
Copyright © 2011-2022 走看看