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

 

转载于:https://www.cnblogs.com/fzf123/p/3306289.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
洛谷的SPOJ需要注册一个SPOJ账号并进行绑定才能进行交题。您可以按照以下步骤进行注册: 1. 打开洛谷网站(https://www.luogu.com.cn/)并登录您的洛谷账号。 2. 在网站顶部导航栏中找到“题库”选项,将鼠标悬停在上面,然后选择“SPOJ”。 3. 在SPOJ页面上,您会看到一个提示,要求您注册SPOJ账号并进行绑定。点击提示中的链接,将会跳转到SPOJ注册页面。 4. 在SPOJ注册页面上,按照要求填写您的用户名、密码和邮箱等信息,并完成注册。 5. 注册完成后,返回洛谷网站,再次进入SPOJ页面。您会看到一个输入框,要求您输入刚刚注册的SPOJ用户名。输入用户名后,点击“绑定”按钮即可完成绑定。 现在您已经成功注册并绑定了SPOJ账号,可以开始在洛谷的SPOJ题库上刷题了。祝您顺利完成编程练习!\[1\]\[2\] #### 引用[.reference_title] - *1* *3* [(洛谷入门系列,适合洛谷新用户)洛谷功能全解](https://blog.csdn.net/rrc12345/article/details/122500057)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [luogu p7492 序列](https://blog.csdn.net/zhu_yin233/article/details/122051384)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值