您的位置:首页 > 产品设计 > UI/UE

spoj 1043 Can you answer these queries I(线段树)

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

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int N = 50001;
int a
;
int sum
;

struct Node
{
int l, r;
int maxl, maxr, maxn;
} node[N << 2];

void pushup( int i )
{
int lc = i << 1, rc = lc | 1;
node[i].maxl = max( node[lc].maxl, sum[node[lc].r] - sum[node[lc].l - 1] + node[rc].maxl );
node[i].maxr = max( node[rc].maxr, sum[node[rc].r] - sum[node[rc].l - 1] + node[lc].maxr );
node[i].maxn = max( node[lc].maxn, node[rc].maxn );
node[i].maxn = max( node[i].maxn, node[lc].maxr + node[rc].maxl );
}

void build( int i, int l, int r )
{
node[i].l = l, node[i].r = r;
if ( l == r )
{
node[i].maxl = node[i].maxr = node[i].maxn = a[l];
return ;
}
int lc = i << 1, rc = lc | 1, mid = ( l + r ) >> 1;
build( lc, l, mid );
build( rc, mid + 1, r );
pushup(i);
}

Node query( int i, int l, int r )
{
if ( node[i].l == l && node[i].r == r )
{
return node[i];
}
int lc = i << 1, rc = lc | 1, mid = ( node[i].l + node[i].r ) >> 1;
if ( r <= mid )
{
return query( lc, l, r );
}
else if ( l > mid )
{
return query( rc, l, r );
}
else
{
Node ln = query( lc, l, mid ), rn = query( rc, mid + 1, r ), res;
res.maxl = max( ln.maxl, sum[mid] - sum[l - 1] + rn.maxl );
res.maxr = max( rn.maxr, sum[r] - sum[mid] + ln.maxr );
res.maxn = max( ln.maxn, rn.maxn );
res.maxn = max( res.maxn, ln.maxr + rn.maxl );
return res;
}
}

int main ()
{
int n, m;
while ( scanf("%d", &n) != EOF )
{
sum[0] = 0;
for ( int i = 1; i <= n; i++ )
{
scanf("%d", a + i);
sum[i] = sum[i - 1] + a[i];
}
build( 1, 1, n );
scanf("%d", &m);
while ( m-- )
{
int x, y;
scanf("%d%d", &x, &y);
Node tmp = query( 1, x, y );
printf("%d\n", tmp.maxn);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: