zoukankan      html  css  js  c++  java
  • POJ 2796 Feel Good 题解

    Bill is developing a new mathematical theory for human emotions. His recent investigations are dedicated to studying how good or bad days influent people's memories about some period of life. 

    A new idea Bill has recently developed assigns a non-negative integer value to each day of human life. 

    Bill calls this value the emotional value of the day. The greater the emotional value is, the better the daywas. Bill suggests that the value of some period of human life is proportional to the sum of the emotional values of the days in the given period, multiplied by the smallest emotional value of the day in it. This schema reflects that good on average period can be greatly spoiled by one very bad day. 

    Now Bill is planning to investigate his own life and find the period of his life that had the greatest value. Help him to do so.

    Input

    The first line of the input contains n - the number of days of Bill's life he is planning to investigate(1 <= n <= 100 000). The rest of the file contains n integer numbers a1, a2, ... an ranging from 0 to 10 6 - the emotional values of the days. Numbers are separated by spaces and/or line breaks.

    Output

    Print the greatest value of some period of Bill's life in the first line. And on the second line print two numbers l and r such that the period from l-th to r-th day of Bill's life(inclusive) has the greatest possible value. If there are multiple periods with the greatest possible value,then print any one of them.

    Sample Input

    6
    3 1 6 4 5 2
    

    Sample Output

    60
    3 5

    思路:要找区间和 * 区间最小值最大的区间,显然,区间最小值固定时区间一定要扩展到最大范围使得区间和最大。可以从前往后枚举最小值元素位置,对于当前最小值,用二分+线段树找出最大可扩展区间,复杂度n*log^2.这样显然有些慢了,可以利用
    manacher的思想,使得每个元素只被扩展一次,可以从大到小枚举元素值,然后扩展就行了,如果他向右扩展到r,如果r之前被扩展过,那么r肯定也是一个被扩展区间的端点,直接跳到另外一个顶点就行了,扩展结束时维护一下当前得到的扩展区间的端点
    信息。直接按元素值枚举的话是(O(Max_A + n)), TLE了,排一下序然后再枚举的话是O(nlogn),这样就过了。
     1 #include <iostream>
     2 #include <fstream>
     3 #include <sstream>
     4 #include <cstdlib>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <string>
     8 #include <cstring>
     9 #include <algorithm>
    10 #include <queue>
    11 #include <stack>
    12 #include <vector>
    13 #include <set>
    14 #include <map>
    15 #include <list>
    16 #include <iomanip>
    17 #include <cctype>
    18 #include <cassert>
    19 #include <bitset>
    20 #include <ctime>
    21 
    22 using namespace std;
    23 
    24 #define pau system("pause")
    25 #define ll long long
    26 #define pii pair<int, int>
    27 #define pb push_back
    28 #define mp make_pair
    29 #define clr(a, x) memset(a, x, sizeof(a))
    30 
    31 const double pi = acos(-1.0);
    32 const int INF = 0x3f3f3f3f;
    33 const int MOD = 1e9 + 7;
    34 const double EPS = 1e-9;
    35 
    36 /*
    37 #include <ext/pb_ds/assoc_container.hpp>
    38 #include <ext/pb_ds/tree_policy.hpp>
    39 
    40 using namespace __gnu_pbds;
    41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
    42 */
    43 
    44 int n, a[100015], mmp[100015], ans_l = 1, ans_r = 1;
    45 ll sum[100015], ans;
    46 struct gg {
    47     int i, x;
    48     gg () {}
    49     gg (int i, int x) : i(i), x(x) {}
    50     bool operator < (const gg &g) const {
    51         return x > g.x;}
    52 } g[100015];
    53 //vector<int> pos[1000015];
    54 int main() {
    55     scanf("%d", &n);
    56     for (int i = 1; i <= n; ++i) {
    57         scanf("%d", &a[i]);
    58         sum[i] = sum[i - 1] + a[i];
    59         //pos[a[i]].pb(i);
    60         g[i].i = i, g[i].x = a[i];
    61     }
    62     sort(g + 1, g + n + 1);
    63     for (int i = 1; i <= n; ++i) {
    64         int p = g[i].i, l = p, r = p;
    65         while (l > 1 && mmp[l - 1]) {
    66             l = mmp[l - 1];
    67         }
    68         while (r < n && mmp[r + 1]) {
    69             r = mmp[r + 1];
    70         }
    71         mmp[l] = r, mmp[r] = l;
    72         ll tans = (ll)g[i].x * (sum[r] - sum[l - 1]);
    73         if (ans < tans) {
    74             ans = tans;
    75             ans_l = l, ans_r = r;
    76         }
    77     }
    78     /*for (int i = 1000000; ~i; --i) {
    79         for (vector<int>::iterator it = pos[i].begin(); it != pos[i].end(); ++it) {
    80             int p = *it, l = p, r = p;
    81             while (l > 1 && mmp[l - 1]) {
    82                 l = mmp[l - 1];
    83             }
    84             while (r < n && mmp[r + 1]) {
    85                 r = mmp[r + 1];
    86             }
    87             mmp[l] = r, mmp[r] = l;
    88             ll tans = (ll)i * (sum[r] - sum[l - 1]);
    89             if (ans < tans) {
    90                 ans = tans;
    91                 ans_l = l, ans_r = r;
    92             }
    93         }
    94     }*/
    95     printf("%lld
    %d %d", ans, ans_l, ans_r);
    96     return 0;
    97 }
  • 相关阅读:
    解决struts2在(IE,Firefox)下载文件名乱码问题
    Quartz 使用
    SpringBoot 全局异常处理器
    数据结构学习(五) Java链表实现队列
    数据结构学习(四) Java链表实现
    Linux 端口占用情况查看
    数据结构学习(三) 基于动态数组实现队列Queue
    数据结构学习(二)基于动态数组实现Stack(栈)
    SpringBoot 定时任务
    数据结构学习(一) Java中的动态数组实现
  • 原文地址:https://www.cnblogs.com/BIGTOM/p/8492869.html
Copyright © 2011-2022 走看看