SPOJ GSS1 && GSS3 (无更新/更新单点,并询问区间最大连续和)

http://www.spoj.com/problems/GSS1/

题意:无更新询问区间最大连续和。

做法:线段树每个节点维护sum[rt],maxsum[rt],lsum[rt],rsum[rt],分别区间和、区间最大和、区间左端最大和和区间右端最大和。

  查询时按从左到右扫,维护ans为最大连续和,rans为到该段的右端最大连续和,扫到每一段时有:

  ans = max(ans,maxsum[rt]);

  ans = max(ans,rans+lsum[rt]);
  rans = max(rsum[rt],rans+sum[rt]);

 1 /*

 2  *Author:       Zhaofa Fang

 3  *Created time: 2013-09-05-22.18 星期四

 4  */

 5 #include <cstdio>

 6 #include <cstdlib>

 7 #include <sstream>

 8 #include <iostream>

 9 #include <cmath>

10 #include <cstring>

11 #include <algorithm>

12 #include <string>

13 #include <utility>

14 #include <vector>

15 #include <queue>

16 #include <map>

17 #include <set>

18 using namespace std;

19 

20 typedef long long ll;

21 typedef pair<int,int> PII;

22 #define DEBUG(x) cout<< #x << ':' << x << endl

23 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)

24 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)

25 #define REP(i,n) for(int i=0;i<(n);i++)

26 #define REPD(i,n) for(int i=(n-1);i>=0;i--)

27 #define PII pair<int,int>

28 #define PB push_back

29 #define ft first

30 #define sd second

31 #define lowbit(x) (x&(-x))

32 #define INF (1<<30)

33 #define eps (1e-8)

34 

35 #define lson l , m , rt<<1

36 #define rson m + 1 , r , rt<<1|1

37 const int maxn = 50011;

38 int sum[maxn<<2],maxsum[maxn<<2],lsum[maxn<<2],rsum[maxn<<2];

39 int rans,ans;

40 void pushUp(int l,int r,int rt){

41     sum[rt] = sum[rt<<1] + sum[rt<<1|1];

42     maxsum[rt] = max(maxsum[rt<<1],maxsum[rt<<1|1]);

43     maxsum[rt] = max(maxsum[rt],rsum[rt<<1]+lsum[rt<<1|1]);

44     lsum[rt] = max(lsum[rt<<1],sum[rt<<1]+lsum[rt<<1|1]);

45     rsum[rt] = max(rsum[rt<<1|1],sum[rt<<1|1]+rsum[rt<<1]);

46 }

47 void build(int l,int r,int rt){

48     if(l == r){

49         scanf("%d",&sum[rt]);

50         lsum[rt] = rsum[rt] = maxsum[rt] = sum[rt];

51         return;

52     }

53     int m = (l + r) >> 1;

54     build(lson);

55     build(rson);

56     pushUp(l,r,rt);

57 }

58 void query(int L,int R,int l,int r,int rt){

59     if(L <= l && r <= R){

60         ans = max(ans,maxsum[rt]);

61         ans = max(ans,rans+lsum[rt]);

62         rans = max(rsum[rt],rans+sum[rt]);

63         return;

64     }

65     int m = (l + r) >> 1;

66     if(L <= m)query(L,R,lson);

67     if(m < R)query(L,R,rson);

68 }

69 int main(){

70     //freopen("in","r",stdin);

71     //freopen("out","w",stdout);

72     int n;

73     while(~scanf("%d",&n)){

74         build(1,n,1);

75         int Q;

76         scanf("%d",&Q);

77         while(Q--){

78             int l,r;

79             scanf("%d%d",&l,&r);

80             ans = rans = -INF;

81             query(l,r,1,n,1);

82             printf("%d\n",ans);

83         }

84     }

85     return 0;

86 }
View Code

 http://www.spoj.com/problems/GSS3/

题意:更新单点,询问区间最大连续和。

做法:做法与GSS1差不多,多了个修改。

  1 /*

  2  *Author:       Zhaofa Fang

  3  *Created time: 2013-09-13-12.56 星期五

  4  */

  5 #include <cstdio>

  6 #include <cstdlib>

  7 #include <sstream>

  8 #include <iostream>

  9 #include <cmath>

 10 #include <cstring>

 11 #include <algorithm>

 12 #include <string>

 13 #include <utility>

 14 #include <vector>

 15 #include <queue>

 16 #include <map>

 17 #include <set>

 18 using namespace std;

 19 

 20 typedef long long ll;

 21 typedef pair<int,int> PII;

 22 #define DEBUG(x) cout<< #x << ':' << x << endl

 23 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)

 24 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)

 25 #define REP(i,n) for(int i=0;i<(n);i++)

 26 #define REPD(i,n) for(int i=(n-1);i>=0;i--)

 27 #define PII pair<int,int>

 28 #define PB push_back

 29 #define ft first

 30 #define sd second

 31 #define lowbit(x) (x&(-x))

 32 #define INF (1<<30)

 33 #define eps (1e-8)

 34 

 35 #define lson l , m , rt<<1

 36 #define rson m + 1 , r , rt<<1|1

 37 

 38 const int maxn = 50011;

 39 int sum[maxn<<2],lsum[maxn<<2],rsum[maxn<<2],mx[maxn<<2];

 40 

 41 void pushUp(int rt){

 42     sum[rt] = sum[rt<<1] + sum[rt<<1|1];

 43     mx[rt] = max(mx[rt<<1],mx[rt<<1|1]);

 44     mx[rt] = max(mx[rt],rsum[rt<<1] + lsum[rt<<1|1]);

 45 

 46     lsum[rt] = max(lsum[rt<<1],sum[rt<<1] + lsum[rt<<1|1]);

 47     rsum[rt] = max(rsum[rt<<1|1],sum[rt<<1|1]+rsum[rt<<1]);

 48 }

 49 void build(int l,int r,int rt){

 50     if(l == r){

 51         scanf("%d",&sum[rt]);

 52         mx[rt] = lsum[rt] = rsum[rt] = sum[rt];

 53         return ;

 54     }

 55     int m = (l + r) >> 1;

 56     build(lson);

 57     build(rson);

 58     pushUp(rt);

 59 }

 60 void update(int k,int val,int l,int r,int rt){

 61     if(l == k && k == r){

 62         mx[rt] = lsum[rt] = rsum[rt] = sum[rt] = val;

 63         return;

 64     }

 65     int m = (l + r) >> 1;

 66     if(k <= m)update(k,val,lson);

 67     else update(k,val,rson);

 68     pushUp(rt);

 69 }

 70 int ans,lans;

 71 void query(int L,int R,int l,int r,int rt){

 72     if(L <= l && r <= R){

 73         ans = max(ans,mx[rt]);

 74         ans = max(ans,lans+lsum[rt]);

 75         lans = max(lans+sum[rt],rsum[rt]);

 76         return;

 77     }

 78     int m = (l + r) >> 1;

 79     if(L <= m)query(L,R,lson);

 80     if(m < R)query(L,R,rson);

 81 }

 82 int main(){

 83     //freopen("in","r",stdin);

 84     //freopen("out","w",stdout);

 85     int n;

 86     while(~scanf("%d",&n)){

 87         build(1,n,1);

 88         int Q;

 89         scanf("%d",&Q);

 90         while(Q--){

 91             int op,x,y;

 92             scanf("%d%d%d",&op,&x,&y);

 93             if(!op)update(x,y,1,n,1);

 94             else {

 95                 ans = lans = -INF;

 96                 query(x,y,1,n,1);

 97                 printf("%d\n",ans);

 98             }

 99         }

100     }

101     return 0;

102 }
View Code

 

你可能感兴趣的:(poj)