[题解] SPOJ GSS1 - Can you answer these queries I

· 题目大意

要求维护一段长度为 \(n\) 的静态序列的区间最大子段和。

有 \(m\) 次询问,每次询问输出区间 \([L,R]\) 的最大子段和。

\(|a[i]| \leq 15007\),\(1 \leq m,n\leq5\times10^4\)

· 解题思路

首先想到如果用线段树的方法,那么预处理时间复杂度为\(O(n)\),总询问复杂度为\(O(m\cdot logn)\)。

当然这么想在这一题中没问题,但是如\(m\)的范围更大一点呢?比如\(1 \leq m \leq 1 \times10^7\)。这时候如果用线段树,很有可能会\(TLE\)。

既然没有修改,那么可以用\(ST\)表或者猫树这种 \(O(1)\) 查询的数据结构来完成这一题,于是笔者选择用猫树来完成这一题。

因为ST表太丑了(doge)

总时间复杂度为\(O(n\cdot logn+m)\)

· 代码实现

注释在代码里

#include <cstdio>
#include <algorithm>
#include <ctype.h>
#define reg register
using namespace std;
namespace io {
template<typename T>inline void read(T &x) {
char f=0,ch; x = 0;
while(!isdigit(ch=getchar())) f |= ch == '-';
while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
x = f? -x: x;
}
char ch[20];
template<typename T>inline void write(T x) {
(x < 0) && (x = -x, putchar('-'));
x || putchar('0');
reg int i=0;
while(x) ch[i++] = x % 10 ^ 48, x /= 10;
while(i) putchar(ch[--i]);
}
}//快读快写
#define rd io::read
#define wt io::write
const int maxN = 100020;
struct CatTree {
int pre, sum;
}t[maxN << 1][22];//维护一下区间前缀/后缀最大值,用于合并,然后维护一下区间子串最大值
int d[maxN << 1], pos[maxN << 1], a[maxN << 1];
int len=2, n, m;
void init(int, int, int);
int query(int, int);
int main() {
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
rd(n);
while(len < n) len <<= 1;
for(reg int i = 1; i <= n; ++i) rd(a[i]);
for(reg int i = 1; i <= len << 1; ++i) d[i] = d[i >> 1] + 1;
init(1, 1, len);
rd(m);
for(reg int i = 1, l, r; i <= m; ++i) {
rd(l); rd(r);
printf("%d\n", query(l, r));
}
return 0;
}
void init(int k, int l, int r) {
if (l==r) {pos[l]=k;return;}
int mid = l + r >> 1, pre , str;
pre = str = t[mid][d[k]].sum = t[mid][d[k]].pre = a[mid];
str = max(str, 0);
for(reg int i = mid - 1; i >= l; --i) {
pre += a[i], str += a[i];
t[i][d[k]].sum = max(t[i + 1][d[k]].sum, str);
t[i][d[k]].pre = max(t[i + 1][d[k]].pre, pre);str = max(str, 0);
}//处理左边区间子串最大值和左边区间后缀最大值。
pre = str = t[mid + 1][d[k]].sum = t[mid + 1][d[k]].pre = a[mid + 1];
str = max(str, 0);
for(reg int i = mid + 2; i <= r; ++i) {
pre += a[i], str += a[i];
t[i][d[k]].sum = max(t[i - 1][d[k]].sum, str);
t[i][d[k]].pre = max(t[i - 1][d[k]].pre, pre);str = max(str, 0);
}
init(k << 1, l, mid);init(k << 1 | 1, mid + 1, r);
}
int query(int l, int r) {
if (l == r) return a[l];
int fa = d[pos[l]] - d[pos[l] ^ pos[r]];//找到x和y的LCA
return max(max(t[l][fa].sum, t[r][fa].sum), t[l][fa].pre + t[r][fa].pre);
}
//最后答案就等于Max{左边的区间子串最大值,右边的区间子串最大值,左边的后缀最大值+右边的前缀最大值}

[题解] SPOJ GSS1 - Can you answer these queries I的更多相关文章

  1. SPOJ GSS1 - Can you answer these queries I(线段树维护GSS)

    Can you answer these queries I SPOJ - GSS1 You are given a sequence A[1], A[2], -, A[N] . ( |A[i]| ≤ ...

  2. SPOJ GSS1 Can you answer these queries I[线段树]

    Description You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A q ...

  3. SPOJ GSS1 Can you answer these queries I

    Time Limit: 115MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Description You are g ...

  4. SPOJ GSS1 Can you answer these queries I ——线段树

    [题目分析] 线段树裸题. 注意update的操作,写结构体里好方便. 嗯,没了. [代码] #include <cstdio> #include <cstring> #inc ...

  5. SPOJ GSS3 Can you answer these queries III[线段树]

    SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...

  6. GSS7 spoj 6779. Can you answer these queries VII 树链剖分+线段树

    GSS7Can you answer these queries VII 给出一棵树,树的节点有权值,有两种操作: 1.询问节点x,y的路径上最大子段和,可以为空 2.把节点x,y的路径上所有节点的权 ...

  7. 线段树 SP1043 GSS1 - Can you answer these queries I

    SP1043 GSS1 - Can you answer these queries I 题目描述 给出了序列A[1],A[2],-,A[N]. (a[i]≤15007,1≤N≤50000).查询定义 ...

  8. GSS3 SPOJ 1716. Can you answer these queries III gss1的变形

    gss2调了一下午,至今还在wa... 我的做法是:对于询问按右区间排序,利用splay记录最右的位置.对于重复出现的,在splay中删掉之前出现的位置所在的节点,然后在splay中插入新的节点.对于 ...

  9. 题解【SP1043】 GSS1 - Can you answer these queries I

    题目描述 You are given a sequence \(A_1, A_2, ..., A_n(|A_i|≤15007,1≤N≤50000)\). A query is defined as f ...

随机推荐

  1. BZOJ2457 双端队列 题解

    本题直接求解十分困难,因为在不知道整个序列的数字规律时当前所作决策都无法保证最优性. 考虑正难则反,题目转化为将一个非降序列分成尽量少的几段,让每段对应原问题的双端队列. 先将原数组排序,由于原数组下 ...

  2. UnitTest+HTMLTestRunner实战

    框架 步骤 先建立images,reports,tools文件夹 把HTMLTestRunner.py放进tools中  文件内容  https://www.cnblogs.com/wangxue13 ...

  3. 深入刨析tomcat 之---第14篇 对应19章,使用manager管理 web应用

    writedby 张艳涛 第19章讲的是管理程序,当一个tomcat启动的时候,能通过远程浏览器能访问tomcat,启动web应用,关闭web应用,查看web应用 怎么实现的呢? 在webapp 文件 ...

  4. Intouch 制作自定义登录弹窗

    在新的自动化项目中,因为业主对设计审美要求比较高,对Intouch自带脚本呼出登录窗体不满意,故而制作自定义登录弹窗来满足其审美需求.在寻求自控群前辈的经验下,将其整理成博客,供大家参考. 1.登录窗 ...

  5. Python小白的数学建模课-12.非线性规划

    非线性规划是指目标函数或约束条件中包含非线性函数的规划问题,实际就是非线性最优化问题. 从线性规划到非线性规划,不仅是数学方法的差异,更是解决问题的思想方法的转变. 非线性规划问题没有统一的通用方法, ...

  6. YsoSerial 工具常用Payload分析之Common-Collections2、4(五)

    前言 Common-Collections <= 3.2.1 对应与YsoSerial为CC1.3.5.6.7 ,Commno-collections4.0对应与CC2.4. 这篇文章结束官方原 ...

  7. JAVA集合类概览

    带着问题来阅读 1.Java有哪些集合 2.不同集合的应用场景分别是哪些 3.哪些实现类是线程安全的 4.为什么Java集合不能存放基本类型 5.集合的fail-fast和fail-safe是什么 J ...

  8. TypeScript学习笔记(一)环境搭建和数据类型

    目录 一.学习TypeScript的缘由 二.学习环境的搭建 1. TypeScript的编译环境 2. vscode自动编译的配置 三.TypeScript中的数据类型 1. 简单变量的定义和初始化 ...

  9. xubuntu共享打印机

    by 无若 1.查看系统中的打印机lpstat -ssystem default destination: HP-Color-LaserJet-CP1215device for HP-Color-La ...

  10. Cloud-init的安装和使用 --以ubuntu-server-14.04-amd64为例

    by hyc 1.Cloud-init安装 已有了一个安装好系统的镜像. 镜像名:ubuntu-test-14.04-server-amd64.img 用户名:user 密码:1 主机名:ubuntu ...