LA 3938 "Ray, Pass me the dishes!"
2013-06-13 20:01
288 查看
这题写的比较蛋疼,看着刘汝佳大神的书写的,还写了一天,真是惭愧啊,思路和书上当然是一样的,维护最大连续和的区间、最大前缀和的区间以及最大后缀和的区间就行了,但是感觉不太好写,之前写完了敲了很多测试数据也没看出错误,wa了好几次,后来实在没办法,又重头到尾扫了几遍,改了几个bug才终于A掉了。
#include <iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<map> #include<queue> #include<stack> #include<cmath> #include<vector> #define inf 0x3f3f3f3f #define Inf 0x3FFFFFFFFFFFFFFFLL #define eps 1e-9 #define pi acos(-1.0) using namespace std; typedef long long ll; const int maxn=500010<<1; const int maxm=500000+10; ll sum[maxm]; int maxsubx[maxn<<1],maxsuby[maxn<<1],maxprefix[maxn<<1],maxsuffix[maxn<<1]; void PushUp(int l,int r,int rt) { int m=(l+r)>>1; ll maxsum=sum[maxsuby[rt<<1]]-sum[maxsubx[rt<<1]-1]; maxsubx[rt]=maxsubx[rt<<1]; maxsuby[rt]=maxsuby[rt<<1]; if(maxsum<sum[maxprefix[rt<<1|1]]-sum[maxsuffix[rt<<1]-1]) { maxsum=sum[maxprefix[rt<<1|1]]-sum[maxsuffix[rt<<1]-1]; maxsubx[rt]=maxsuffix[rt<<1]; maxsuby[rt]=maxprefix[rt<<1|1]; } if(maxsum<sum[maxsuby[rt<<1|1]]-sum[maxsubx[rt<<1|1]-1]) { maxsum=sum[maxsuby[rt<<1|1]]-sum[maxsubx[rt<<1|1]-1]; maxsubx[rt]=maxsubx[rt<<1|1]; maxsuby[rt]=maxsuby[rt<<1|1]; } maxsum=sum[maxprefix[rt<<1]]-sum[l-1]; maxprefix[rt]=maxprefix[rt<<1]; if(maxsum<sum[maxprefix[rt<<1|1]]-sum[l-1]) { maxsum=sum[maxprefix[rt<<1|1]]-sum[l-1]; maxprefix[rt]=maxprefix[rt<<1|1]; } maxsum=sum[r]-sum[maxsuffix[rt<<1]-1]; maxsuffix[rt]=maxsuffix[rt<<1]; if(maxsum<sum[r]-sum[maxsuffix[rt<<1|1]-1]) { maxsuffix[rt]=maxsuffix[rt<<1|1]; } /*maxsum=sum[r]-sum[maxsuffix[rt<<1|1]-1]; //maxsuffix[rt]=maxsuffix[rt<<1|1]; if(maxsum<=sum[r]-sum[maxsuffix[rt<<1]-1]) { maxsuffix[rt]=maxsuffix[rt<<1]; }*/ } void build(int l,int r,int rt) { if(l==r) { maxsubx[rt]=maxsuby[rt]=l; maxprefix[rt]=maxsuffix[rt]=l; return; } int m=(l+r)>>1; build(l,m,rt<<1); build(m+1,r,rt<<1|1); PushUp(l,r,rt); } void Query(int L,int R,int l,int r,int rt,int &x,int &y,int &pre,int &suf) { if(l>=L&&r<=R) { x=maxsubx[rt]; y=maxsuby[rt]; pre=maxprefix[rt]; suf=maxsuffix[rt]; return; } int xa,ya,xb,yb,pa,sa,pb,sb; int m=(l+r)>>1; if(m>=L&&m<R) { Query(L,R,l,m,rt<<1,xa,ya,pa,sa); Query(L,R,m+1,r,rt<<1|1,xb,yb,pb,sb); ll maxsum=sum[ya]-sum[xa-1]; x=xa;y=ya; if(maxsum<sum[pb]-sum[sa-1]) { maxsum=sum[pb]-sum[sa-1]; x=sa; y=pb; } if(maxsum<sum[yb]-sum[xb-1]) { maxsum=sum[yb]-sum[xb-1]; x=xb; y=yb; } maxsum=sum[pa]-sum[L-1]; pre=pa; if(maxsum<sum[pb]-sum[L-1]) { pre=pb; } maxsum=sum[R]-sum[sa-1]; suf=sa; if(maxsum<sum[R]-sum[sb-1]) { suf=sb; } /*maxsum=sum[R]-sum[sb-1]; suf=sb; if(maxsum<=sum[R]-sum[sa-1]) { suf=sa; }*/ return; } if(m>=L) { Query(L,R,l,m,rt<<1,xa,ya,pa,sa); x=xa; y=ya; pre=pa; suf=sa; } else if(m<R) { Query(L,R,m+1,r,rt<<1|1,xb,yb,pb,sb); x=xb; y=yb; pre=pb; suf=sb; } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n,m; int tcase=0; while(~scanf("%d%d",&n,&m)) { tcase++; sum[0]=0; for(int i=1;i<=n;++i) { scanf("%lld",&sum[i]); sum[i]+=sum[i-1]; } build(1,n,1); printf("Case %d:\n",tcase); int l,r,x,y,p,s; for(int i=0;i<m;++i) { scanf("%d%d",&l,&r); Query(l,r,1,n,1,x,y,p,s); printf("%d %d\n",x,y); } } return 0; }
相关文章推荐
- UVALive 3938 "Ray, Pass me the dishes!"
- LA-3938-"Ray, Pass me the dishes!" 解题报告
- LA 3938 "Ray, Pass me the dishes!" / 线段树单点更新
- UVa 3938 "Ray, Pass me the dishes!"
- LA3938:"Ray, Pass me the dishes!"(线段树)
- UVALive - 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!"(线段树)
- LA3938 "Ray, Pass me the dishes!" (线段树区间合并)
- uva 1400 "Ray, Pass me the dishes!"
- Uva 1400 "Ray, Pass me the dishes!" (线段树 区间合并)
- UVALive3938 "Ray, Pass me the dishes!" 线段树动态区间最大和
- UvaLA 3938 "Ray, Pass me the dishes!"
- UVALive - 3938 "Ray, Pass me the dishes!"
- UVA1400 - "Ray, Pass me the dishes!"
- UVA 1400 1400 - "Ray, Pass me the dishes!"(线段树)
- 线段树(区间合并) LA 3989 "Ray, Pass me the dishes!"
- uvalive 3938 - "Ray, Pass me the dishes!" +动态最大连续和+线段树
- LA3938 & UVA1400 - Ray, Pass me the dishes!(线段树)