UVa Ray, Pass me the dishes! (线段树)
来源:互联网 发布:c语言水仙花数程序 编辑:程序博客网 时间:2024/05/16 01:58
白书上的线段树例题。
题意 : 给你一个数组,然后有m次询问,每次询问一个区间,返回在这个区间里面最大的连续和的起始和结束位置、
思路 :每个节点记录前缀max_pre和和后缀和max_suf来维护它的最大连续和max_sub。(其实思路白书上讲了,就是代码实现而已)需要注意的是这道题目的max_pre,max_suf,max_sub都是需要用long long 来保存的。
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long lld;const int MAXN = 500005;const int INF = 100000007;struct MAX{lld Max;int l,r;};struct node{MAX sub, pre, suf;lld sum;}ans[MAXN<<2];int n,m;void init(node &a,int v){MAX e;e.Max = v;e.l = -INF; e.r = INF;a.pre = a.sub = a.suf = e;a.sum = v;}void push_up(node &mid,node &ll,node &rr){mid.sum = ll.sum + rr.sum;if (ll.pre.Max >= rr.pre.Max + ll.sum){mid.pre = ll.pre;}else{mid.pre.Max = rr.pre.Max + ll.sum;mid.pre.l = ll.pre.l;mid.pre.r = rr.pre.r;}if (rr.suf.Max > rr.sum + ll.suf.Max){mid.suf = rr.suf;}else{mid.suf.Max = rr.sum + ll.suf.Max;mid.suf.l = ll.suf.l;mid.suf.r = rr.suf.r;}lld temp = ll.suf.Max + rr.pre.Max;lld t1 = ll.sub.Max, t2 = rr.sub.Max;if (t1 >= temp && t1 >= t2){mid.sub = ll.sub;}else if (temp >= t1 && temp >= t2){mid.sub.Max = temp;mid.sub.l = ll.suf.l;mid.sub.r = rr.pre.r;}else{mid.sub = rr.sub;}}void update(int rt,int L,int R,int p,int v){if (L == R){ans[rt].sub.Max = ans[rt].pre.Max = ans[rt].suf.Max = v;ans[rt].sum = v;ans[rt].sub.l = ans[rt].sub.r = p;ans[rt].pre.l = ans[rt].pre.r = p;ans[rt].suf.l = ans[rt].suf.r = p;}else{int M = (L + R) >> 1;if (p <= M)update(rt<<1,L,M,p,v);else update(rt<<1|1,M+1,R,p,v);if (ans[rt<<1].sum != -INF){if (ans[rt<<1|1].sum != -INF)push_up(ans[rt],ans[rt<<1],ans[rt<<1|1]);else ans[rt] = ans[rt<<1];}else ans[rt] = ans[rt<<1|1];}}node query(int rt,int L,int R,int l,int r){int M = (L + R) >> 1;node tl,tr,res;init(tl,-INF); init(tr,-INF);if (L >= l && R <= r)return ans[rt];if (M >= l){tl = query(rt<<1,L,M,l,r);}if (r > M){tr = query(rt<<1|1,M+1,R,l,r);}if (tl.sum != -INF){if (tr.sum != -INF){push_up(res,tl,tr);return res;}else return tl;}else return tr;}int main(){int cas = 1 , i;while (scanf("%d%d",&n,&m) == 2){for (i = 1;i <= 4*n;i++)init(ans[i],-INF);for (i = 1;i <= n;i++){int a;scanf("%d",&a);update(1,1,n,i,a);}printf("Case %d:\n",cas++);while (m--){int ql,qr;scanf("%d%d",&ql,&qr);node res = query(1,1,n,ql,qr);printf("%d %d\n",res.sub.l,res.sub.r);}}return 0;}
- UVa Ray, Pass me the dishes! (线段树)
- UVA 1400 "Ray, Pass me the dishes!" (线段树)
- UVA 1400 1400 - "Ray, Pass me the dishes!"(线段树)
- uva 1400 "Ray, Pass me the dishes!" 线段树
- uva 1400 - "Ray, Pass me the dishes!"(线段树)
- UVA - 1400"Ray, Pass me the dishes!"(线段树)
- UVa 1400 "Ray, Pass me the dishes!"(线段树)
- UVA 1400 "Ray, Pass me the dishes!"(线段树)
- UVALive - 3938 "Ray, Pass me the dishes!" (线段树)
- uvalive 3938 Ray, Pass me the dishes!(线段树)
- 线段树(1):点修改 (uva 1400 Ray,Pass me the Dishes)
- UVa 1400 Ray, Pass me the dishes!(线段树:复杂段查询)
- UVA live 3938 - "Ray, Pass me the dishes!"(线段树)
- UVa-1400 - "Ray, Pass me the dishes!"
- UVa 3938 "Ray, Pass me the dishes!"
- uva 1400 "Ray, Pass me the dishes!"
- UVA 1400 Ray, Pass me the dishes!
- LA 3938 - "Ray, Pass me the dishes!"(线段树)
- Android自动化测试工具——Monkey
- 2013-BIT程序设计 14.古罗马的加法
- hdu 4490 Mad Veterinarian(bfs)
- mysql 合并列 函数 GROUP_CONCAT
- Android如何防止apk程序被反编译
- UVa Ray, Pass me the dishes! (线段树)
- 向其他进程注入代码的三种方法
- 嵌入式第一张ppt整理
- 进程间通信——Interprocess communication
- SD/MMC/SDIO 概念区分概要
- Android APK反编译详解(附图)
- sql server数据库的恢复
- 数据库性能优化之冗余字段的作用
- android LinearLayout和RelativeLayout实现精确布局