SPOJ GSS1 静态区间求解最大子段和

 题目大意:

给定n个数,再给q个区间询问,希望在区间s,t中找到一段连续的子序列使其和最大

 

因为询问上万,节点数50000,明显是用线段树去做,这里很明显的区间更新,唯一写起来有点恶心的是询问

每一个区间的最大都要跟左右区间的左最大右最大有关系

反正时要注意细节了,查询的时候同时要查询其左右连续最大

 

自己的错误在于左右连续最大的更新出问题,这个希望自己以后要注意

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <iostream>

 4 #include <algorithm>

 5 #include <set>

 6 #include <map>

 7 using namespace std;

 8 

 9 const int INF = 0x3fffffff;

10 #define N 50010

11 #define MOD 100007

12 #define ls o<<1

13 #define rs o<<1|1

14 #define define_m int m=(l+r)>>1

15 

16 int ml[N*3] , mr[N*3] , mx[N*3] , sum[N*3];

17 int a[N] , pre[N] , n;

18 

19 void push_up(int o)

20 {

21     mx[o] = max(mx[ls] , mx[rs]);

22     mx[o] = max(mx[o] , ml[rs]+mr[ls]);

23     ml[o] = max(ml[ls],sum[ls]+ml[rs]) , mr[o] = max(mr[rs],sum[rs]+mr[ls]);

24     sum[o] = sum[ls]+sum[rs];

25 }

26 

27 void build(int o , int l , int r)

28 {

29     if(l==r){

30         sum[o]=ml[o]=mr[o]=mx[o]=a[l];

31         return;

32     }

33     define_m;

34     build(ls , l , m);

35     build(rs , m+1 , r);

36     push_up(o);

37 }

38 

39 void query(int o , int l , int r , int s , int t , int &ansl , int &ansr , int &ans)

40 {

41     if(l>=s && r<=t){

42         ans = mx[o];

43         ansl = ml[o];

44         ansr = mr[o];

45         return ;

46     }

47     define_m;

48     if(m>=t) query(ls , l , m , s , t , ansl , ansr , ans);

49     else if(m<s) query(rs , m+1 , r , s , t , ansl , ansr ,ans);

50     else{

51         int t1,t2,t3,t4,t5,t6;

52         query(ls , l , m , s , m , t1 , t2 , t3);

53         query(rs , m+1 , r , m+1 , t , t4 , t5 , t6);

54         ansl = max(t1 , pre[m]-pre[s-1]+t4) , ansr = max(t5 , pre[t]-pre[m]+t2);

55         ans = max(t3 , t6);

56         ans = max(ans , t2+t4);

57     }

58     //cout<<o<<" "<<l<<" "<<r<<" "<<s<<" "<<t<<" "<<ansl<<" "<<ansr<<" "<<ans<<endl;

59 }

60 

61 int main()

62 {

63     #ifndef ONLINE_JUDGE

64         freopen("a.in" , "r" , stdin);

65     #endif // ONLINE_JUDGE

66     while(~scanf("%d" , &n))

67     {

68         for(int i=1 ; i<=n ; i++){

69             scanf("%d" , a+i);

70             pre[i] = pre[i-1]+a[i];

71         }

72         build(1 , 1 , n);

73         int m;

74         scanf("%d" , &m);

75         for(int i=0 ; i<m ; i++){

76             int s , t;

77             scanf("%d%d" , &s , &t);

78             int t1,t2,t3;

79             query(1,1,n,s,t,t1,t2,t3);

80             printf("%d\n" , t3);

81         }

82     }

83     return 0;

84 }

 

你可能感兴趣的:(poj)