「SP1043」GSS1 - Can you answer these queries I

传送门
Luogu

解题思路

这题就是 GSS3 的一个退化版,不带修改操作的区间最大子段和,没什么好讲的。

细节注意事项

  • 咕咕咕

参考代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
    s = 0; int f = 0; char c = getchar();
    while (!isdigit(c)) f |= (c == '-'), c = getchar();
    while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
    s = f ? -s : s;
}

const int _ = 50000 + 10;

int n, m, a[_];
struct node{ int sum, L, R, mx; }t[_ << 2];

inline int lc(int p) { return p << 1; }

inline int rc(int p) { return p << 1 | 1; }

inline void pushup(int p) {
    t[p].sum = t[lc(p)].sum + t[rc(p)].sum;
    t[p].L = max(t[lc(p)].L, t[lc(p)].sum + t[rc(p)].L);
    t[p].R = max(t[rc(p)].R, t[rc(p)].sum + t[lc(p)].R);
    t[p].mx = max(t[lc(p)].R + t[rc(p)].L, max(t[lc(p)].mx, t[rc(p)].mx));
}

inline void build(int p = 1, int l = 1, int r = n) {
    if (l == r) { t[p] = (node) { a[l], a[l], a[l], a[l] }; return; }
    int mid = (l + r) >> 1;
    build(lc(p), l, mid), build(rc(p), mid + 1, r), pushup(p);
}

inline node query(int ql, int qr, int p = 1, int l = 1, int r = n) {
    if (ql <= l && r <= qr) return t[p];
    int mid = (l + r) >> 1;
    if (ql > mid) return query(ql, qr, rc(p), mid + 1, r);
    if (qr <= mid) return query(ql, qr, lc(p), l, mid);
    node ls = query(ql, mid, lc(p), l, mid);
    node rs = query(mid + 1, qr, rc(p), mid + 1, r);
    node res;
    res.sum = ls.sum + rs.sum;
    res.L = max(ls.L, ls.sum + rs.L);
    res.R = max(rs.R, rs.sum + ls.R);
    res.mx = max(ls.R + rs.L, max(ls.mx, rs.mx));
    return res;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.in", "r", stdin);
#endif
    read(n);
    for (rg int i = 1; i <= n; ++i) read(a[i]);
    build();
    read(m);
    for (int ql, qr; m--; )
        read(ql), read(qr), printf("%d\n", query(ql, qr).mx);
    return 0;
}

完结撒花 \(qwq\)

原文地址:https://www.cnblogs.com/zsbzsb/p/11746542.html

时间: 2024-11-12 19:06:00

「SP1043」GSS1 - Can you answer these queries I的相关文章

【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+a{i+1}+...+a_j:x \leq i \leq j \leq y }\). 给定M个查询,程序必须输出这些查询的结果. Input 输入文件的第一行包含整数\(n\). 在第二行,\(n\)个数字跟随. 第三行包含整数\(m\). \(m\)行跟在后面,其中第\(1\)行包含两个数字\(

「SP2713」GSS4 - Can you answer these queries IV

传送门 Luogu 解题思路 区间开方以及区间求和. 考虑用线段树来做. 开方操作看似没有任何结合律可言,但这题有另外一个性质: 一个数的初始值不超过 \(10^{18}\) ,而这个数被开方6次左右就可以到1或0,并且1和0都是不需要再开方的. 所以我们记一下每个节点代表区间的最大值,若该值小于等于1,那么就不需要再进入下一层递归,否则就向下递归修改,修改次数最坏也不过是 \(O(6n)\) 左右,线段树完全没压力,于是这题就做完了. 细节注意事项 咕咕咕 参考代码 #include <alg

SPOJ GSS1 Can you answer these queries I

Can you answer these queries I Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on SPOJ. Original ID: GSS164-bit integer IO format: %lld      Java class name: Main You are given a sequence $A[1], A[2], ..., A[N] $. $( |A[i]| \leq

[SP1043]GSS1 - Can you answer these queries I

求区间内最大非空子段和,没什么可说的吧. 线段树,每个区间维护从左端开始的最大非空子段和,区间内的最大非空子段和,以右端结束的最大非空子段和,还有区间和. pushup()的写法要注意,不要漏掉任何一种情况. 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 using namespace std; 6 inline int re

SP1043 GSS1 - Can you answer these queries I(线段树,区间最大子段和(静态))

题目描述 给出了序列A[1],A[2],…,A[N]. (a[i]≤15007,1≤N≤50000).查询定义如下: 查询(x,y)=max{a[i]+a[i+1]+...+a[j]:x≤i≤j≤y}. 给定M个查询,程序必须输出这些查询的结果. 输入输出格式 输入格式: 输入文件的第一行包含整数N. 在第二行,N个数字跟随. 第三行包含整数M. M行跟在后面,其中第1行包含两个数字xi和yi. 输出格式: 您的程序应该输出M查询的结果,每一行一个查询. 思路: 我们做这道题首先应该想的,是两个

SP1043 GSS1 - Can you answer these queries I(猫树)

给出了序列A[1],A[2],…,A[N]. (a[i]≤15007,1≤N≤50000).查询定义如下: 查询(x,y)=max{a[i]+a[i+1]+...+a[j]:x≤i≤j≤y}. 给定M个查询,程序必须输出这些查询的结果. 这就是一个最大子段和,用线段树就能直接搞掉 然后这里学习了一下一个叫做猫树的神奇东西->这里 能做到预处理之后查询$O(1)$ 1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 us

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

问题描述 LG-SP1043 题解 GSS 系列第一题. \(q\) 个询问,求 \([x,y]\) 的最大字段和. 线段树,维护 \([x,y]\) 的 \(lmax,rmax,sum,val\) ,向上合并即可. 但是注意询问过程中也需要维护这些信息. \(\mathrm{Code}\) #include<bits/stdc++.h> using namespace std; template <typename Tp> void read(Tp &x){ x=0;ch

GSS1 - Can you answer these queries I(线段树)

前言 线段树菜鸡报告,stO ZCDHJ Orz,GSS基本上都切完了. Solution 考虑一下用线段树维护一段区间左边连续的Max,右边的连续Max,中间的连续Max还有总和,发现这些东西可以相互合并,然后直接写就好了. #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<algorithm> #include<queue&

另一个画风的GSS1 - Can you answer these queries I(猫树)

前言 其实我觉得你看猫锟的解释也看不懂(主要是还有一些不良心的讲解者不讲清楚,当然这里不是针对了qwq) 猫锟链接 Solution 考虑我们的线段树是个啥玩意? 每一层都是一堆区间叠在一起. 我们在每一个节点维护的又是什么? 左边的max,右边的max,中间的max,还有sum. 那么我们改变一下: 令\(p_{dps,i}\)表示在深度为\(dps\)的线段树上\(i\)这个节点所在区间的左边的max,右边的max,然后就可以在\(build\)的时候求 再令\(p_{dps,i}\)表示在