SPOJ1043 GSS1(线段树)
题意
给出$n$个数,每次询问区间$(l, r)$内最大字段和
Sol
在合并子树的时候,答案仅有四种情况
打四个标记维护即可
查询同理,用类似update的方式合并
注意查询的时候不能按照以前的方式写,因为不知道变量的下界,最稳妥的办法就是判三种情况
/* */
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<cmath>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
//#define int long long
#define LL long long
#define rg register
#define sc(x) scanf("%d", &x);
#define pt(x) printf("%d ", x);
#define db(x) double x
#define rep(x) for(int i = 1; i <= x; i++)
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1<<22, stdin), p1 == p2) ? EOF : *p1++)
char buf[( << )], *p1 = buf, *p2 = buf;
char obuf[<<], *O = obuf;
#define OS *O++ = '\n';
using namespace std;
using namespace __gnu_pbds;
const int MAXN = , INF = 1e9 + , mod = 1e9 + ;
const double eps = 1e-;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
void print(int x) {
if(x > ) print(x / );
*O++ = x % + '';
}
#define ls k << 1
#define rs k << 1 | 1
int N, M;
int a[MAXN];
struct Node {
int l, r, lmx, rmx, mx, sum;
}T[MAXN << ];
void update(int k) {
T[k].sum = T[ls].sum + T[rs].sum;
T[k].mx = max(T[ls].mx, T[rs].mx);
T[k].mx = max(T[k].mx, T[ls].rmx + T[rs].lmx);
T[k].rmx = max(T[rs].rmx, T[rs].sum + T[ls].rmx);
T[k].lmx = max(T[ls].lmx, T[ls].sum + T[rs].lmx);
}
void Build(int k, int ll, int rr) {
T[k] = (Node) {ll, rr, , , };
if(ll == rr) {
T[k].lmx = T[k].rmx = T[k].mx = T[k].sum = a[ll];
return ;
}
int mid = ll + rr >> ;
Build(ls, ll, mid);
Build(rs, mid + , rr);
update(k);
}
Node merge(Node a, Node b) {
Node now;
now.sum = a.sum + b.sum;
now.mx = max(a.mx, b.mx);
now.mx = max(now.mx, a.rmx + b.lmx);
now.rmx = max(b.rmx, b.sum + a.rmx);
now.lmx = max(a.lmx, a.sum + b.lmx);
// printf("%d %d %d %d\n", now.mx, now.lmx, now.rmx, now.sum);
return now;
}
Node Query(int k, int ll, int rr) {
Node ans = (Node) {, , , , };
if(ll <= T[k].l && T[k].r <= rr) return T[k];
int mid = T[k].l + T[k].r >> ;
/*if(ll <= mid) ans = Query(ls, ll, rr);
if(rr > mid) ans = merge(ans, Query(rs, ll, rr)); WA!*/
if(ll > mid) return Query(rs, ll, rr);
else if(rr <= mid) return Query(ls, ll, rr);
else return merge(Query(ls, ll, rr), Query(rs, ll, rr));
return ans;
}
main() {
//freopen("a.in", "r", stdin);
N = read();
for(int i = ; i <= N; i++) a[i] = read();
Build(, , N);
int M = read();
while(M--) {
int x = read(), y = read();
printf("%d\n", Query(, x, y).mx);
}
//fwrite(obuf, O-obuf, 1 , stdout);
return ;
}
/*
5
-10 12 1 -45 134
5
1 5
2 3
4 5
1 4
3 5
*/
SPOJ1043 GSS1(线段树)的更多相关文章
- SPOJ - GSS1 —— 线段树 (结点信息合并)
题目链接:https://vjudge.net/problem/SPOJ-GSS1 GSS1 - Can you answer these queries I #tree You are given ...
- GSS1 - Can you answer these queries I(线段树)
前言 线段树菜鸡报告,stO ZCDHJ Orz,GSS基本上都切完了. Solution 考虑一下用线段树维护一段区间左边连续的Max,右边的连续Max,中间的连续Max还有总和,发现这些东西可以相 ...
- 线段树【SP1043】GSS1 - Can you answer these queries I
Description 给出了序列\(A_1,A_2,-,A_n\). \(a_i \leq 15007,1 \leq n \leq 50000\).查询定义如下: 查询\((x,y)=max{a_i ...
- SPOJ GSS1 Can you answer these queries I ——线段树
[题目分析] 线段树裸题. 注意update的操作,写结构体里好方便. 嗯,没了. [代码] #include <cstdio> #include <cstring> #inc ...
- SP1043 GSS1 - Can you answer these queries I 线段树
问题描述 LG-SP1043 题解 GSS 系列第一题. \(q\) 个询问,求 \([x,y]\) 的最大字段和. 线段树,维护 \([x,y]\) 的 \(lmax,rmax,sum,val\) ...
- CF380C. Sereja and Brackets[线段树 区间合并]
C. Sereja and Brackets time limit per test 1 second memory limit per test 256 megabytes input standa ...
- SPOJ GSS1_Can you answer these queries I(线段树区间合并)
SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...
- SPOJ1557 GSS2 Can you answer these queries II 历史最值线段树
传送门 题意:给出一个长度为$N$的数列,$Q$次询问,每一次询问$[l,r]$之间的最大子段和,相同的数只计算一次.所有数字的绝对值$\leq 10^5$ GSS系列中不板子的大火题,单独拿出来写 ...
- SPOJ GSS3 Can you answer these queries III ——线段树
[题目分析] GSS1的基础上增加修改操作. 同理线段树即可,多写一个函数就好了. [代码] #include <cstdio> #include <cstring> #inc ...
随机推荐
- Anniversary party (树形DP)
There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The Un ...
- vbox安装64位ubuntu
如果不做任何设置的话,你会发现下载下来的vbox只能安装32位的系统,如果想要安装64位的系统,我们需要做一些配置: 进入bios(basic input output system), Securi ...
- UnityError 打包到Android错误解决
- mysql5.5.28.tar.gz编译安装操作笔记
1.yum安装依赖包 yum install wget gcc gcc-c++ make cmake ncurses-devel libtool zilib-devel -y 2.创建mysql用 ...
- AngularJs在ng-click函数中如何获取代表当前元素的DOM对象
<!DOCTYPE html> <html> <head> <title></title> <script src="lib ...
- Oracle单行函数。。。
单行函数 --字符函数--1.ASCII 返回与指定的字符对应的十进制数;select ascii('A') A,ascii('a') a,ascii('0') zero,ascii(' ') spa ...
- 解决Maven依赖下载不全的问题
背景描述 在日常学习过程中使用Maven构建SpringBoot+SpringCloud服务时,有时会使用非正式版的SpringBoot和SpringCloud(非正式版是指不是最终发布的版本,而是测 ...
- yum 安装Tomcat7(centos)
yum 安装Tomcat7 其实最重要的就是yum源吗.初始源的里面既没有nginx也没有tomcat7. 1,搞定nginx,她家自己有源的: rpm -ivh http://nginx.org ...
- <Android 基础(二)> BroadcastReceiver
介绍 BroadcastReceiver:广播接收者,很形象,广播发送,类比生活中的广播,有能力听得到的都可以介绍到这个信息,然后在大脑中反映.对应到Android中就是SendBroadcast和o ...
- git学习(一)
提: 远程的主机名(远程仓库服务器名): origin 本地的主分支: master(本地master分支) 远程的主分支: maste(远程仓库的master分支) gi ...