SPOJ GSS1 && GSS3 (无更新/更新单点,并询问区间最大连续和)
2013-09-06 21:39
363 查看
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]);
View Code
题意:无更新询问区间最大连续和。
做法:线段树每个节点维护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]);
/* *Author: Zhaofa Fang *Created time: 2013-09-13-12.56 星期五 */ #include <cstdio> #include <cstdlib> #include <sstream> #include <iostream> #include <cmath> #include <cstring> #include <algorithm> #include <string> #include <utility> #include <vector> #include <queue> #include <map> #include <set> using namespace std; typedef long long ll; typedef pair<int,int> PII; #define DEBUG(x) cout<< #x << ':' << x << endl #define FOR(i,s,t) for(int i = (s);i <= (t);i++) #define FORD(i,s,t) for(int i = (s);i >= (t);i--) #define REP(i,n) for(int i=0;i<(n);i++) #define REPD(i,n) for(int i=(n-1);i>=0;i--) #define PII pair<int,int> #define PB push_back #define ft first #define sd second #define lowbit(x) (x&(-x)) #define INF (1<<30) #define eps (1e-8) #define lson l , m , rt<<1 #define rson m + 1 , r , rt<<1|1 const int maxn = 50011; int sum[maxn<<2],lsum[maxn<<2],rsum[maxn<<2],mx[maxn<<2]; void pushUp(int rt){ sum[rt] = sum[rt<<1] + sum[rt<<1|1]; mx[rt] = max(mx[rt<<1],mx[rt<<1|1]); mx[rt] = max(mx[rt],rsum[rt<<1] + lsum[rt<<1|1]); lsum[rt] = max(lsum[rt<<1],sum[rt<<1] + lsum[rt<<1|1]); rsum[rt] = max(rsum[rt<<1|1],sum[rt<<1|1]+rsum[rt<<1]); } void build(int l,int r,int rt){ if(l == r){ scanf("%d",&sum[rt]); mx[rt] = lsum[rt] = rsum[rt] = sum[rt]; return ; } int m = (l + r) >> 1; build(lson); build(rson); pushUp(rt); } void update(int k,int val,int l,int r,int rt){ if(l == k && k == r){ mx[rt] = lsum[rt] = rsum[rt] = sum[rt] = val; return; } int m = (l + r) >> 1; if(k <= m)update(k,val,lson); else update(k,val,rson); pushUp(rt); } int ans,lans; void query(int L,int R,int l,int r,int rt){ if(L <= l && r <= R){ ans = max(ans,mx[rt]); ans = max(ans,lans+lsum[rt]); lans = max(lans+sum[rt],rsum[rt]); return; } int m = (l + r) >> 1; if(L <= m)query(L,R,lson); if(m < R)query(L,R,rson); } int main(){ //freopen("in","r",stdin); //freopen("out","w",stdout); int n; while(~scanf("%d",&n)){ build(1,n,1); int Q; scanf("%d",&Q); while(Q--){ int op,x,y; scanf("%d%d%d",&op,&x,&y); if(!op)update(x,y,1,n,1); else { ans = lans = -INF; query(x,y,1,n,1); printf("%d\n",ans); } } } return 0; }
View Code
相关文章推荐
- 线段树基本操作(单点更新,区间更新,区间最大最小值,区间和)poj3468&poj3264&hdu1698&&hdu1166&hdu1754
- HDU 1540 / POJ 2892 Tunnel Warfare (单点更新,区间合并,求包含某点的最大连续个数)
- POJ 题目2892 Tunnel Warfare(线段树单点更新查询,求单点所在最大连续区间长度)
- hdu 1540 Tunnel Warfare(单点更新,取最大连续区间)★
- SPOJ GSS1 Can you answer these queries I (线段树求区间最大连续和)
- SPOJ - QTREE(树链剖分 + 单点更新 + 区间查询)
- HDU4262–Juggler(区间求和&&单点更新)
- FZU Problem 2240 Daxia & Suneast's problem(博弈+[单点更新,区间查询]线段树)
- SPOJ 375 QTREE - Query on a tree 树链剖分+线段树(单点更新 区间查询最值)
- hdu 1754 线段树区间最大值 单点更新
- poj 3667 线段树成端更新区间最大连续和
- 单点更新查询区间最大值 hdu1754 I hate it
- [BZOJ] 1012 - [JSOI2008] - 最大数maxnumber - 线段树 - 单点更新 - 区间查询最大
- 线段树(单点更新,区间求最大值)
- HDU 1754 B I Hate It 线段树 单点更新 区间最大值 模板
- CodeForce 356A Knight Tournament(线段树的区间更新+单点询问)
- hdu 1754 线段树区间最大值 单点更新
- hdu 1754 线段树 单点更新 动态区间最大值
- 线段树(单点更新,区间求最大值)
- HDU 1754 B I Hate It 线段树 单点更新 区间最大值 模板