• CF#67 75d Big Maximum Sum


    ~~~题面~~~

    题解:

      观察到拼接后的数据范围过大,无法O(n)解决,但是大区间是由很多小区间组成,而小区间是固定的,不会变化,所以可以考虑预处理出每个小区间的信息,然后根据给定序列按顺序一步一步合并区间信息。

      跟线段树维护区间最大子段和类似,要合并2个区间我们只需要知道如下信息:

      前缀最大子段和,后缀最大子段和,当前区间最大子段和。

      那么转移方式如下:

      1,对于区间最大子段和而言,要么是继承2个区间中的某个最大子段和,要么是用上一个区间的后缀最大子段和+后一个区间的前缀最大子段和凑成一个子段和作为新的最大子段和,所以3者取max即可。

      2,对于前缀最大值而言,,,其实我们在转移的时候并不需要用到上一个区间的前缀最大值,因此无需再次维护。

      3,对于后缀最大值而言,要么是继承后一个区间的后缀最大子段和,要么是上一个区间的后缀最大值+后一个区间的整个区间凑成的新后缀最大值,2者取max即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define R register int
     4 #define AC 50
     5 #define ac 5000
     6 #define LL long long
     7 
     8 int n, m, len;
     9 LL l[AC], r[AC], mx[AC], sum[AC], ans, rr;
    10 int s[ac];
    11 
    12 inline int read()
    13 {
    14     int x = 0;char c = getchar();bool z = false;
    15     while(c > '9' || c < '0') 
    16     {
    17         if(c == '-') z = true;
    18         c = getchar();
    19     }
    20     while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    21     if(!z) return x;
    22     else return -x;
    23 }
    24 
    25 inline void upmax(LL &a, LL b)
    26 {
    27     if(b > a) a = b;
    28 }
    29 
    30 void pre()
    31 {
    32     n = read(), m = read();
    33     for(R i = 1; i <= n; i ++)
    34     {
    35         len = read();
    36         for(R j = 1; j <= len; j ++) s[j] = read(), sum[i] += s[j];
    37         LL tmp = 0;
    38         for(R j = 1; j <= len; j ++) tmp += s[j], upmax(l[i], tmp);
    39         tmp = 0;
    40         for(R j = len; j; j --) tmp += s[j], upmax(r[i], tmp);
    41         tmp = 0;
    42         for(R j = 1; j <= len; j ++)
    43         {
    44             tmp += s[j];
    45             upmax(mx[i], tmp);
    46             if(tmp < 0) tmp = 0;
    47         }
    48     }
    49 }
    50 
    51 void work()
    52 {
    53     int x;
    54     x = read();
    55     rr = r[x], ans = mx[x];
    56     for(R i = 2; i <= m; i ++)
    57     {
    58         x = read();//读入右区间
    59         upmax(ans, mx[x]);
    60         upmax(ans, rr + l[x]);
    61         rr = rr + sum[x];
    62         upmax(rr, r[x]);
    63     }
    64     cout << ans << endl;
    65 }
    66 
    67 int main()
    68 {
    69     //freopen("in.in", "r", stdin);
    70     pre();
    71     work();
    72     //fclose(stdin);
    73     return 0;
    74 }
    View Code
  • 相关阅读:
    pyc文件是什么【转载】
    Linux下的python等操作【转载】
    P1012 拼数 字符串
    P1309 瑞士轮 排序选择 时间限制 归并排序
    商业竞争 三分+背包
    老虎ji 剪枝模拟
    交通灯 并查集
    三色抽卡游戏 博弈论nim
    质数串 乱搞
    自动驾驶系统 bfs
  • 原文地址:https://www.cnblogs.com/ww3113306/p/9847522.html
Copyright © 2020-2023  润新知