SPOJ GSS5 Can you answer these queries V
Time Limit: 132MS | Memory Limit: 1572864KB | 64bit IO Format: %lld & %llu |
Description
You are given a sequence A[1], A[2], ..., A
. ( |A[i]| <= 10000 , 1 <= N <= 10000 ). A query is defined as follows: Query(x1,y1,x2,y2) = Max { A[i]+A[i+1]+...+A[j] ; x1 <= i <= y1 , x2 <= j <= y2 and x1 <= x2 , y1 <= y2 }. Given M queries (1 <= M <= 10000), your program must output the results of these queries.
Input
The first line of the input consist of the number of tests cases <= 5. Each case consist of the integer N and the sequence A. Then the integer M. M lines follow, contains 4 numbers x1, y1, x2 y2.
Output
Your program should output the results of the M queries for each test case, one query per line.
Example
Input: 2 6 3 -2 1 -4 5 2 2 1 1 2 3 1 3 2 5 1 1 1 1 1 1 1 Output: 2 3 1
Hint
Added by: | Frank Rafael Arteaga |
Date: | 2008-08-06 |
Time limit: | 0.132s |
Source limit: | 50000B |
Memory limit: | 1536MB |
Cluster: | Cube (Intel G860) |
Languages: | All except: C99 strict ERL JS NODEJS PERL 6 VB.net |
Resource: | K.-Y. Chen and K.-M. Chao, On the Range Maximum-Sum Segment Query Problem, 2007. |
又是查询最大连续字段和,但是限制了左右端点所在的区间……
线段树的部分不需要改动,计算答案的时候改一下即可。
如果区间有重复部分,就把区间分成三段,左段里找左端点,右段里找右端点,然后并上中段。有一串麻烦的判断,具体看代码。
如果区间没有重复部分,就左段里找左端点,右段里找右端点,然后强制加上两区间中间的序列和。
/*by SilverN*/ #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #define lc rt<<1 #define rc rt<<1|1 using namespace std; const int mxn=100010; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m; int data[mxn]; struct node{ int mx; int ml,mr; int smm; }t[mxn<<2],tmp0; void Build(int l,int r,int rt){ if(l==r){t[rt].mx=t[rt].ml=t[rt].mr=data[l];t[rt].smm=data[l];return;} int mid=(l+r)>>1; Build(l,mid,lc); Build(mid+1,r,rc); t[rt].smm=t[lc].smm+t[rc].smm; t[rt].mx=max(t[lc].mx,t[rc].mx); t[rt].mx=max(t[lc].mr+t[rc].ml,t[rt].mx); t[rt].ml=max(t[lc].ml,t[lc].smm+t[rc].ml); t[rt].mr=max(t[rc].mr,t[rc].smm+t[lc].mr); return; } node query(int L,int R,int l,int r,int rt){ // printf("%d %d %d %d %d\n",L,R,l,r,rt); if(R<L){ return (node){0,0,0,0}; } if(L<=l && r<=R){return t[rt];} int mid=(l+r)>>1; node res1; if(L<=mid)res1=query(L,R,l,mid,lc); else res1=tmp0; node res2; if(R>mid)res2=query(L,R,mid+1,r,rc); else res2=tmp0; node res={0}; res.smm=res1.smm+res2.smm; res.mx=max(res1.mx,res2.mx); res.mx=max(res.mx,res1.mr+res2.ml); res.ml=max(res1.ml,res1.smm+res2.ml); res.mr=max(res2.mr,res2.smm+res1.mr); return res; } int qsum(int L,int R,int l,int r,int rt){ if(L<=l && r<=R)return t[rt].smm; int mid=(l+r)>>1; int res=0; if(L<=mid)res+=qsum(L,R,l,mid,lc); if(R>mid)res+=qsum(L,R,mid+1,r,rc); return res; } int main(){ int T; T=read(); while(T--){ n=read(); int i,j,x0,y0,x2,y2; for(i=1;i<=n;i++)data[i]=read(); Build(1,n,1); m=read(); tmp0.ml=tmp0.mr=tmp0.mx=-1e9;tmp0.smm=0; for(i=1;i<=m;i++){ x0=read();y0=read();x2=read();y2=read(); int tmp=0; int ans=-1e9; if(y0>=x2){ //区间重叠 node res=query(x2,y0,1,n,1); node res1=query(x0,x2-1,1,n,1); node res2=query(y0+1,y2,1,n,1); ans=max(ans,res1.mr+res.smm+res2.ml); ans=max(ans,res1.mr+res.ml); ans=max(ans,res.mr+res2.ml); ans=max(ans,res.mx); } else{ //区间未重叠 if(y0+1<x2)tmp=qsum(y0+1,x2-1,1,n,1); node res1=query(x0,y0,1,n,1); node res2=query(x2,y2,1,n,1); ans=max(ans,tmp+res1.mr+res2.ml); } //printf("%d\n",query(x2,y2,1,n,1).mx); printf("%d\n",ans); } } return 0; }
- SPOJ GSS5 Can you answer these queries V
- SPOJ GSS5 Can you answer these queries V
- SPOJ GSS5 Can you answer these queries V
- [SPOJ GSS5] Can you answer these queries V [线段树]
- SPOJ GSS5 Can you answer these queries V ——线段树
- SPOJ 6779 Can you answer these queries VII
- SPOJ GSS2 Can you answer these queries II
- spoj(GSS3) 1716 Can you answer these queries III(线段树求最大子段和)
- spoj 1557 Can you answer these queries II (gss2)线段树
- spoj 4487. Can you answer these queries VI (gss6) splay 常数优化
- spoj 2916 Can you answer these queries V
- spoj 1043——Can you answer these queries I
- SPOJ GSS2 Can you answer these queries II
- spoj 1043. Can you answer these queries I (线段树)
- SPOJ 4487. Can you answer these queries VI(GSS6) splay
- SPOJ 2916 Can you answer these queries V(GSS5 线段树)
- Spoj 2713 Can you answer these queries IV 水线段树
- SPOJ GSS1 Can you answer these queries I
- 数据结构(线段树):SPOJ GSS3 - Can you answer these queries III
- SPOJ GSS3 Can you answer these queries III