码迷,mamicode.com
首页 > 其他好文 > 详细

spoj 1043 线段树

时间:2015-07-30 22:57:38      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:

线段树在解决区间合并问题上还是很强力的,每个结点维护三个值: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\n", tmp.maxn);
84         }        
85     }
86     return 0;
87 }

 

spoj 1043 线段树

标签:

原文地址:http://www.cnblogs.com/huoxiayu/p/4690812.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!