SP1716 GSS3 - Can you answer these queries III
Posted chy-2003
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SP1716 GSS3 - Can you answer these queries III相关的知识,希望对你有一定的参考价值。
问题分析
解法一
简单的一道线段树维护\(lmax,rmax,max,sum\)即可。
解法二
考虑动态DP。
\[
\beginaligned
\left [ \beginmatrix
a_i&-\infty&a_i\a_i&0&a_i\\-\infty & -\infty &0
\endmatrix\right ]
\left [\beginmatrix
f_i-1\g_i-1\0
\endmatrix\right]
=
\left [\beginaligned
f_i\g_i\0
\endaligned\right]
\endaligned
\]
然后线段树维护即可。
参考程序
解法一
#include <bits/stdc++.h>
using namespace std;
const int Maxn = 50010;
struct node
int LeftMax, RightMax, Max, Sum;
node()
node( int _LeftMax, int _RightMax, int _Max, int _Sum) :
LeftMax( _LeftMax ), RightMax( _RightMax ), Max( _Max ), Sum( _Sum )
inline node operator + ( const node Other ) const
return node( max( LeftMax, Sum + Other.LeftMax ),
max( Other.RightMax, Other.Sum + RightMax ),
max( max( Max, Other.Max ), RightMax + Other.LeftMax ),
Sum + Other.Sum );
inline void Give( int x )
LeftMax = RightMax = Max = Sum = x;
return;
;
node Tree[ Maxn << 2 ];
int n, m, A[ Maxn ];
void Build( int Index, int Left, int Right )
if( Left == Right )
Tree[ Index ].Give( A[ Left ] );
return;
int Mid = ( Left + Right ) >> 1;
Build( Index << 1, Left, Mid );
Build( Index << 1 | 1, Mid + 1, Right );
Tree[ Index ] = Tree[ Index << 1 ] + Tree[ Index << 1 | 1 ];
return;
void Change( int Index, int Left, int Right, int Pos, int Key )
if( Left == Right )
Tree[ Index ].Give( Key );
return;
int Mid = ( Left + Right ) >> 1;
if( Pos <= Mid ) Change( Index << 1, Left, Mid, Pos, Key );
if( Pos > Mid ) Change( Index << 1 | 1, Mid + 1, Right, Pos, Key );
Tree[ Index ] = Tree[ Index << 1 ] + Tree[ Index << 1 | 1 ];
return;
node Query( int Index, int Left, int Right, int L, int R )
if( L <= Left && Right <= R ) return Tree[ Index ];
int Mid = ( Left + Right ) >> 1;
if( R <= Mid ) return Query( Index << 1, Left, Mid, L, R );
if( L > Mid ) return Query( Index << 1 | 1, Mid + 1, Right, L, R );
return Query( Index << 1, Left, Mid, L, R ) + Query( Index << 1 | 1, Mid + 1, Right, L, R );
int main()
scanf( "%d", &n );
for( int i = 1; i <= n; ++i ) scanf( "%d", A + i );
Build( 1, 1, n );
scanf( "%d", &m );
for( int i = 1; i <= m; ++i )
int Opt, l, r;
scanf( "%d%d%d", &Opt, &l, &r );
if( Opt == 0 ) Change( 1, 1, n, l, r );
if( Opt == 1 ) printf( "%d\n", Query( 1, 1, n, l, r ).Max );
return 0;
解法二
#include <bits/stdc++.h>
using namespace std;
const int Maxn = 50010;
const int INF = 1000000000;
struct matrix
int A[ 3 ][ 3 ];
matrix()
for( int i = 0; i < 3; ++i )
for( int j = 0; j < 3; ++j )
A[ i ][ j ] = -INF;
return;
matrix( int x )
A[ 0 ][ 0 ] = A[ 0 ][ 2 ] = A[ 1 ][ 0 ] = A[ 1 ][ 2 ] = x;
A[ 0 ][ 1 ] = A[ 2 ][ 0 ] = A[ 2 ][ 1 ] = -INF;
A[ 1 ][ 1 ] = A[ 2 ][ 2 ] = 0;
return;
inline matrix operator * ( const matrix Other ) const
matrix Ans = matrix();
for( int i = 0; i < 3; ++i )
for( int j = 0; j < 3; ++j )
for( int k = 0; k < 3; ++k )
Ans.A[ i ][ j ] = max( Ans.A[ i ][ j ], A[ i ][ k ] + Other.A[ k ][ j ] );
return Ans;
;
int n, m, A[ Maxn ];
matrix Tree[ Maxn << 2 ];
void Build( int Index, int Left, int Right )
if( Left == Right )
Tree[ Index ] = matrix( A[ Left ] );
return;
int Mid = ( Left + Right ) >> 1;
Build( Index << 1, Left, Mid );
Build( Index << 1 | 1, Mid + 1, Right );
Tree[ Index ] = Tree[ Index << 1 ] * Tree[ Index << 1 | 1 ];
return;
void Change( int Index, int Left, int Right, int Pos, int Key )
if( Left == Right )
Tree[ Index ] = matrix( Key );
return;
int Mid = ( Left + Right ) >> 1;
if( Pos <= Mid ) Change( Index << 1, Left, Mid, Pos, Key );
if( Pos > Mid ) Change( Index << 1 | 1, Mid + 1, Right, Pos, Key );
Tree[ Index ] = Tree[ Index << 1 ] * Tree[ Index << 1 | 1 ];
return;
matrix Query( int Index, int Left, int Right, int L, int R )
if( L <= Left && Right <= R ) return Tree[ Index ];
int Mid = ( Left + Right ) >> 1;
if( R <= Mid ) return Query( Index << 1, Left, Mid, L, R );
if( L > Mid ) return Query( Index << 1 | 1, Mid + 1, Right, L, R );
return Query( Index << 1, Left, Mid, L, R ) * Query( Index << 1 | 1, Mid + 1, Right, L, R );
int main()
scanf( "%d", &n );
for( int i = 1; i <= n; ++i ) scanf( "%d", &A[ i ] );
Build( 1, 1, n );
scanf( "%d", &m );
for( int i = 1; i <= m; ++i )
int Opt, x, y;
scanf( "%d%d%d", &Opt, &x, &y );
if( Opt == 0 ) Change( 1, 1, n, x, y );
if( Opt == 1 ) printf( "%d\n", Query( 1, 1, n, x, y ).A[ 1 ][ 2 ] );
return 0;
以上是关于SP1716 GSS3 - Can you answer these queries III的主要内容,如果未能解决你的问题,请参考以下文章
SP1716 GSS3 - Can you answer these queries III
SP1716 GSS3 - Can you answer these queries III
SP1716 GSS3 - Can you answer these queries III 线段树
题解 SP1716 GSS3 - Can you answer these queries III