SPOJ 2916 GSS5 - Can you answer these queries V
2024-09-06 11:52:18
解题思路
和GSS1相似,但需要巨恶心的分类讨论,对于x1<=y1< x2< =y2 这种情况 , 最大值应该取[x1,y1]的右端最大+[y1+1,x2-1]的和+[x2,y2]的左端最大。对于x1< =x2< =y1<=y2,用四种情况,第一种是[x1,x2-1]的右端最大+[x2,y2]的左端最大,第二种是[x1,y1]的右端最大+[y1+1,y2]的左端最大,第三种是[x2,y1]的最大值,第四种是[x1,x2-1]的右端最大+[x2,y1]的和+[y1+1,y2]的左端最大。这四种情况取max即为答案。可以画图帮助理解。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 10005;
inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int n,a[MAXN],T,m;
struct Node{
int lx,rx,sum,mx;
Node(){
lx=rx=sum=mx=0;
}
}node[MAXN<<2];
inline void pushup(int x){
node[x].sum=node[x<<1].sum+node[x<<1|1].sum;
node[x].lx=max(node[x<<1].lx,node[x<<1].sum+node[x<<1|1].lx);
node[x].rx=max(node[x<<1|1].rx,node[x<<1].rx+node[x<<1|1].sum);
node[x].mx=max(max(node[x<<1].mx,node[x<<1|1].mx),node[x<<1].rx+node[x<<1|1].lx);
}
inline void build(int x,int l,int r){
if(l==r){
node[x].sum=node[x].lx=node[x].mx=node[x].rx=a[l];
return;
}
int mid=l+r>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
}
inline Node query(int x,int l,int r,int L,int R){
if(L<=l && r<=R) return node[x];
int mid=l+r>>1;
if(mid<L) return query(x<<1|1,mid+1,r,L,R);
else if(mid>=R) return query(x<<1,l,mid,L,R);
else {
Node A=query(x<<1,l,mid,L,R);
Node B=query(x<<1|1,mid+1,r,L,R);
Node ans;
ans.sum=A.sum+B.sum;
ans.lx=max(A.lx,A.sum+B.lx);
ans.rx=max(B.rx,B.sum+A.rx);
ans.mx=max(max(A.mx,B.mx),A.rx+B.lx);
return ans;
}
}
inline Node solve(int x1,int y1,int x2,int y2){
Node A=query(1,1,n,x1,y1);
Node B=query(1,1,n,x2,y2);
Node ans;
if(y1<x2) {
if(x2-1>=y1+1){
Node C=query(1,1,n,y1+1,x2-1);
ans.mx=A.rx+C.sum+B.lx;
}
else ans.mx=A.rx+B.lx;
}
else{
Node C,D,E;
if(x1<=x2-1) C=query(1,1,n,x1,x2-1);
if(y1+1<=y2) D=query(1,1,n,y1+1,y2);
E=query(1,1,n,x2,y1);
ans.mx=max(max(E.mx,C.rx+E.sum+D.lx),max(C.rx+B.lx,A.rx+D.lx));
}
return ans;
}
int main(){
T=rd();
while(T--){
n=rd();
for(register int i=1;i<=n;i++) a[i]=rd();
build(1,1,n);
m=rd();
while(m--){
int x1=rd(),y1=rd(),x2=rd(),y2=rd();
printf("%d\n",solve(x1,y1,x2,y2).mx);
}
}
return 0;
}
最新文章
- 导出Excel通用工具类
- hihoCoder#1121
- 特征脸(Eigenface)理论基础-PCA(主成分分析法)
- Visual C++内存泄露检测—VLD工具使用说明[转]
- 【HDOJ】1667 The Rotation Game
- ConvertHelper与泛型集合
- Slider( 滑动条) 组件
- ACE模板之Jqgrid
- 使用 VS2017 和 js 进行桌面程序开发 - electron 之 Hello Word
- 使用quartz实现不重启服务器修改自定义配置
- 2. 网友对app后端写作系列文章的写作建议
- HBase篇--HBase操作Api和Java操作Hbase相关Api
- Yii2 验证规则
- C# 获取指定路径下的文件结构(树形结构)
- 使用电脑adb给Essential Phone刷机 —(官方篇)
- Spring容器技术内幕之BeanDefinition类介绍
- IOC容器特性注入第四篇:容器初始化
- CVE-2010-2883
- 在Windows下安装Linux
- iOS基础--UIView的常见属性
热门文章
- Mybatis-generator/通用Mapper/Mybatis-Plus对比
- 移植 thttpd Web 服务器
- DMZ在虚拟化环境中的部署
- [转]Entity Framework教程(第二版)
- Lydsy2017省队十连测
- MSI右键添加管理员运行.reg
- 菜鸟nginx源码剖析数据结构篇(一)动态数组ngx_array_t[转]
- VS2010-MFC(对话框:设置对话框控件的Tab顺序)
- Python学习day13-函数进阶(1)
- 我学习python没有记住的东西