zoukankan      html  css  js  c++  java
  • spoj 1043 Can you answer these queries I(线段树)

    线段树在解决区间合并问题上还是很强力的,每个结点维护三个值:maxl, maxr, maxn,然后合并操作见pushup函数。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 
     6 const int N = 50001;
     7 int a[N];
     8 int sum[N];
     9 
    10 struct Node 
    11 {
    12     int l, r;
    13     int maxl, maxr, maxn;
    14 } node[N << 2];
    15 
    16 void pushup( int i )
    17 {
    18     int lc = i << 1, rc = lc | 1;
    19     node[i].maxl = max( node[lc].maxl, sum[node[lc].r] - sum[node[lc].l - 1] + node[rc].maxl );
    20     node[i].maxr = max( node[rc].maxr, sum[node[rc].r] - sum[node[rc].l - 1] + node[lc].maxr );
    21     node[i].maxn = max( node[lc].maxn, node[rc].maxn );
    22     node[i].maxn = max( node[i].maxn, node[lc].maxr + node[rc].maxl );
    23 }
    24 
    25 void build( int i, int l, int r )
    26 {
    27     node[i].l = l, node[i].r = r;
    28     if ( l == r )
    29     {
    30         node[i].maxl = node[i].maxr = node[i].maxn = a[l];
    31         return ;
    32     }
    33     int lc = i << 1, rc = lc | 1, mid = ( l + r ) >> 1;
    34     build( lc, l, mid );
    35     build( rc, mid + 1, r );
    36     pushup(i);
    37 }
    38 
    39 Node query( int i, int l, int r )
    40 {
    41     if ( node[i].l == l && node[i].r == r )
    42     {
    43         return node[i];
    44     }
    45     int lc = i << 1, rc = lc | 1, mid = ( node[i].l + node[i].r ) >> 1;
    46     if ( r <= mid )
    47     {
    48         return query( lc, l, r );
    49     }
    50     else if ( l > mid )
    51     {
    52         return query( rc, l, r );
    53     }
    54     else
    55     {
    56         Node ln = query( lc, l, mid ), rn = query( rc, mid + 1, r ), res;
    57         res.maxl = max( ln.maxl, sum[mid] - sum[l - 1] + rn.maxl );
    58         res.maxr = max( rn.maxr, sum[r] - sum[mid] + ln.maxr );
    59         res.maxn = max( ln.maxn, rn.maxn );
    60         res.maxn = max( res.maxn, ln.maxr + rn.maxl );
    61         return res;
    62     }
    63 }
    64 
    65 int main ()
    66 {
    67     int n, m;    
    68     while ( scanf("%d", &n) != EOF )
    69     {
    70         sum[0] = 0;
    71         for ( int i = 1; i <= n; i++ )
    72         {
    73             scanf("%d", a + i);
    74             sum[i] = sum[i - 1] + a[i];
    75         }
    76         build( 1, 1, n );
    77         scanf("%d", &m);
    78         while ( m-- )
    79         {
    80             int x, y;
    81             scanf("%d%d", &x, &y);
    82             Node tmp = query( 1, x, y );
    83             printf("%d
    ", tmp.maxn);
    84         }        
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    修改电脑安装路径
    快读模板
    ECNU XCPC 2021 OCTOBER TRAINING #1
    System.AccessViolationException处理,HandleProcessCorruptedStateExceptions
    网页打包到apk
    去除服务器的heder信息
    outlook
    华为机试题:计算链路长度
    华为机试题:求子区间面积和
    华为机试题: IPv6地址压缩
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4690812.html
Copyright © 2011-2022 走看看