• SPOJ GSS1 静态区间求解最大子段和


     题目大意:

    给定n个数,再给q个区间询问,希望在区间s,t中找到一段连续的子序列使其和最大

    因为询问上万,节点数50000,明显是用线段树去做,这里很明显的区间更新,唯一写起来有点恶心的是询问

    每一个区间的最大都要跟左右区间的左最大右最大有关系

    反正时要注意细节了,查询的时候同时要查询其左右连续最大

    自己的错误在于左右连续最大的更新出问题,这个希望自己以后要注意

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <set>
     6 #include <map>
     7 using namespace std;
     8 
     9 const int INF = 0x3fffffff;
    10 #define N 50010
    11 #define MOD 100007
    12 #define ls o<<1
    13 #define rs o<<1|1
    14 #define define_m int m=(l+r)>>1
    15 
    16 int ml[N*3] , mr[N*3] , mx[N*3] , sum[N*3];
    17 int a[N] , pre[N] , n;
    18 
    19 void push_up(int o)
    20 {
    21     mx[o] = max(mx[ls] , mx[rs]);
    22     mx[o] = max(mx[o] , ml[rs]+mr[ls]);
    23     ml[o] = max(ml[ls],sum[ls]+ml[rs]) , mr[o] = max(mr[rs],sum[rs]+mr[ls]);
    24     sum[o] = sum[ls]+sum[rs];
    25 }
    26 
    27 void build(int o , int l , int r)
    28 {
    29     if(l==r){
    30         sum[o]=ml[o]=mr[o]=mx[o]=a[l];
    31         return;
    32     }
    33     define_m;
    34     build(ls , l , m);
    35     build(rs , m+1 , r);
    36     push_up(o);
    37 }
    38 
    39 void query(int o , int l , int r , int s , int t , int &ansl , int &ansr , int &ans)
    40 {
    41     if(l>=s && r<=t){
    42         ans = mx[o];
    43         ansl = ml[o];
    44         ansr = mr[o];
    45         return ;
    46     }
    47     define_m;
    48     if(m>=t) query(ls , l , m , s , t , ansl , ansr , ans);
    49     else if(m<s) query(rs , m+1 , r , s , t , ansl , ansr ,ans);
    50     else{
    51         int t1,t2,t3,t4,t5,t6;
    52         query(ls , l , m , s , m , t1 , t2 , t3);
    53         query(rs , m+1 , r , m+1 , t , t4 , t5 , t6);
    54         ansl = max(t1 , pre[m]-pre[s-1]+t4) , ansr = max(t5 , pre[t]-pre[m]+t2);
    55         ans = max(t3 , t6);
    56         ans = max(ans , t2+t4);
    57     }
    58     //cout<<o<<" "<<l<<" "<<r<<" "<<s<<" "<<t<<" "<<ansl<<" "<<ansr<<" "<<ans<<endl;
    59 }
    60 
    61 int main()
    62 {
    63     #ifndef ONLINE_JUDGE
    64         freopen("a.in" , "r" , stdin);
    65     #endif // ONLINE_JUDGE
    66     while(~scanf("%d" , &n))
    67     {
    68         for(int i=1 ; i<=n ; i++){
    69             scanf("%d" , a+i);
    70             pre[i] = pre[i-1]+a[i];
    71         }
    72         build(1 , 1 , n);
    73         int m;
    74         scanf("%d" , &m);
    75         for(int i=0 ; i<m ; i++){
    76             int s , t;
    77             scanf("%d%d" , &s , &t);
    78             int t1,t2,t3;
    79             query(1,1,n,s,t,t1,t2,t3);
    80             printf("%d
    " , t3);
    81         }
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    Camera HAL3学习
    Android GPU呈现模式分析
    Android O版本自定义日志输出目录
    Android Configstore HAL
    Ubuntu下设置adb path的方法
    Ubuntu使用技巧
    PHP学习笔记
    mysql安装
    在ubuntu中安装Python
    OS X在使用<semaphore.h>时报错
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4557228.html
Copyright © 2020-2023  润新知