SPOJ GSS5 Can you answer these queries V (线段树)
来源:互联网 发布:天天炫舞开挂软件下载 编辑:程序博客网 时间:2024/06/05 20:09
比GSS3 麻烦在于要判断两个区间的相交性。
分为三种情况.
1. x1 y1 x2 y2
这种情况就是 x1 y1 的右最大 + sum【y1 x2】 + x2 y2的做最大
2.x1 x2 y2 y1 其实就是 y1==y2的时候
要么区间在 x2-y2之间
要么区间的头在 x1 x2之间,尾在 x2 y2之间
3. x1 x2 y1 y2。
这种情况和2比较像是 这个时候 x1-y2 区间分成三段。只需要枚举头尾各在区间哪个区间就好了。
需要注意的是。 有可能 x2==y1
所以要注意一下比较的时候的边界。
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define maxn 11111 #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e using namespace std; int tre[maxn<<2]; int lef[maxn<<2]; int rig[maxn<<2]; int sum[maxn<<2]; void pushup(int num) { sum[num]=sum[num<<1]+sum[num<<1|1]; lef[num]=max(lef[num<<1],sum[num<<1]+lef[num<<1|1]); rig[num]=max(rig[num<<1|1],sum[num<<1|1]+rig[num<<1]); tre[num]=max(tre[num<<1],max(tre[num<<1|1],lef[num<<1|1]+rig[num<<1])); } void build(int num,int s,int e) { if(s==e) { scanf("%d",&tre[num]); lef[num]=rig[num]=sum[num]=tre[num]; return; } int mid=(s+e)>>1; build(lson); build(rson); pushup(num); } int Q_sum(int num,int s,int e,int l,int r) { if(l>r)return 0; if(l<=s && r>=e) { return sum[num]; } int mid=(s+e)>>1; if(r<=mid)return Q_sum(lson,l,r); else if(l>mid)return Q_sum(rson,l,r); else { return Q_sum(lson,l,mid)+Q_sum(rson,mid+1,r); } } int Q_L(int num,int s,int e,int l,int r) { if(l>r)return 0; if(l<=s && r>=e) { return lef[num]; } int mid=(s+e)>>1; if(r<=mid)return Q_L(lson,l,r); else if(l>mid)return Q_L(rson,l,r); else return max(Q_L(lson,l,mid),Q_sum(lson,l,mid)+Q_L(rson,mid+1,r)); } int Q_R(int num,int s,int e,int l,int r) { if(l>r)return 0; if(l<=s && r>=e) { return rig[num]; } int mid=(s+e)>>1; if(r<=mid)return Q_R(lson,l,r); else if(l>mid)return Q_R(rson,l,r); else return max(Q_R(rson,mid+1,r),Q_sum(rson,mid+1,r)+Q_R(lson,l,mid)); } int query(int num,int s,int e,int l,int r) { if(l>r)return 0; if(l<=s && r>=e) { return tre[num]; } int mid=(s+e)>>1; if(r<=mid)return query(lson,l,r); else if(l>mid)return query(rson,l,r); else { return max(Q_L(rson,mid+1,r)+Q_R(lson,l,mid),max(query(lson,l,mid),query(rson,mid+1,r))); } } int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); build(1,1,n); int m; scanf("%d",&m); while(m--) { int x1,x2,y1,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); if(x2>y1) { printf("%d\n",Q_R(1,1,n,x1,y1)+Q_sum(1,1,n,y1+1,x2-1)+Q_L(1,1,n,x2,y2)); } else if(y1==y2) { printf("%d\n",max(query(1,1,n,x2,y2),Q_L(1,1,n,x2,y2)+Q_R(1,1,n,x1,x2-1))); } else { printf("%d\n",max(Q_R(1,1,n,x1,x2-1)+Q_L(1,1,n,x2,y1),max(Q_R(1,1,n,x1,x2-1)+Q_L(1,1,n,y1+1,y2)+Q_sum(1,1,n,x2,y1),max(Q_R(1,1,n,x2,y1)+Q_L(1,1,n,y1+1,y2),query(1,1,n,x2,y1))))); } } } return 0; }
0 0
- [SPOJ GSS5] Can you answer these queries V [线段树]
- SPOJ 2916 Can you answer these queries V(GSS5 线段树)
- 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
- GSS5 - Can you answer these queries V
- spoj 2916. Can you answer these queries V(线段树)
- 【SPOJ】2916 Can you answer these queries V 线段树
- SPOJ GSS5 Can you answer these queries V(区间合并)
- SPOJ Can you answer these queries V
- SPOJ/GSS3:Can you answer these queries III(线段树)
- spoj 1043. Can you answer these queries I (线段树)
- spoj 1557. Can you answer these queries II(线段树)
- spoj 1716. Can you answer these queries III(线段树)
- spoj 2713. Can you answer these queries IV(线段树)
- SPOJ GSS3 Can you answer these queries III (线段树)
- SPOJ GSS4 Can you answer these queries IV (线段树)
- QT4.8.4 +VS2010 一些个人遇到的错误
- c++ 直接插入排序
- 一道面试题看 HashMap 的存储方式
- hdu3336 KMP + DP 前缀数组出现的次数
- 在MATLAB中实现字符串矩阵
- SPOJ GSS5 Can you answer these queries V (线段树)
- 使用不同版本Gradle构建Andorid 出现Gradle version xxxx is required
- 从 github 上 download 项目后
- Gradle构建Android Project出现java.io.File找不到的问题
- 【MongoDB】3、分布式MongoDB
- Intellij无法同步Gradle, 出现org.gradle.plugins.ide.internal.IdeDependenciesExtractor错误
- c++ 桶排序算法
- 【【【超高仿】】】迅雷播放器教程 -- 总结(14)
- centos 安装 Broadcom无线网卡驱动