• SP1716 GSS3


    题目链接

    问题分析

    解法一

    简单的一道线段树维护(lmax,rmax,max,sum)即可。

    解法二

    考虑动态DP。

    [egin{aligned} left [ egin{matrix} a_i&-infty&a_i\ a_i&0&a_i\-infty & -infty &0 end{matrix} ight ] left [egin{matrix} f_{i-1}\ g_{i-1}\ 0 end{matrix} ight] = left [egin{aligned} f_i\ g_i\ 0 end{aligned} ight] end{aligned} ]

    然后线段树维护即可。

    参考程序

    解法一

    #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
    ", 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
    ", Query( 1, 1, n, x, y ).A[ 1 ][ 2 ] );
    	}
    	return 0;
    }
    
  • 相关阅读:
    CSS 权威指南 CSS实战手册 第四版(阅读笔记)
    iframe交互(一)父页面自动高度
    连接微服务
    学习SQLYog
    sourceTree的安装以及破解
    sql 根据子级ID获取所有父级
    新手Python入门安装(一)
    C# 真正完美的 汉字转拼音
    供应链相关的书和博客
    网易跟帖为什么火
  • 原文地址:https://www.cnblogs.com/chy-2003/p/11502651.html
Copyright © 2020-2023  润新知