首页 > 其他分享 >AcWing245. 你能回答这些问题吗

AcWing245. 你能回答这些问题吗

时间:2022-12-28 22:56:00浏览次数:42  
标签:AcWing245 半边 子段 int qquad 回答 问题 情况 区间

题目描述

给定长度为 \(N\) 的数列 \(A\),以及 \(M\) 条指令,每条指令可能是以下两种之一:

  1. 1 x y,查询区间 \([x,y]\) 中的最大连续子段和
  2. 2 x y,把 \(A[x]\) 改成 \(y\)。

对于每个查询指令,输出一个整数表示答案。

解题思路

\(\qquad\)区间问题首选线段树,那这题我们需要维护那些信息呢
\(\qquad\)首先我们区间最大连续子段和有三种情况,将一个区间\([l,r]\)分成两部分,那么会有如下\(3\)种情况:

\(\qquad\qquad\large a.\)整个子段在左半边

\(\qquad\qquad\large b.\)整个子段在右半边

\(\qquad\qquad\large c.\)左右都包含了这个子段的一部分

对于上面三种情况,我们进行分类讨论:

\(\qquad\)对于\(a\)情况,我们可以直接取左半部分的值
\(\qquad\)对于\(b\)情况也一样。
\(\qquad\)对于\(c\)情况,我们可以再次将他拆成左右两段连续的区间,然后维护左半部分的最大后缀和,维护右半部分的最大前缀和,这样这两个东西加起来就是\(c\)情况的最大连续子段和了。

\(\\\)

\(\qquad\qquad\qquad\qquad\LARGE 那如何维护呢?\)

再次分类讨论:一个区间的最大前缀和有两种情况:

\(\qquad\qquad\qquad a.\)全部在左半边

\(\qquad\qquad\qquad b.\)包含了整个左半边和右半边的最大前缀

\(a. 和 b.\)情况取一个\(Max\)即可

对于后缀的维护也是镜像操作。

代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 5e5 + 10;
int a[N], n, m;

struct Seg 
{
    int l, r;
    int v, sum, lmax, rmax;
} tr[N << 2];

void PushUp(Seg& cur, Seg& L, Seg& R) 
{
    cur.sum = L.sum + R.sum;
    cur.lmax = max(L.lmax, L.sum + R.lmax);
    cur.rmax = max(R.rmax, R.sum + L.rmax);
    cur.v = max(L.v, max(R.v, L.rmax + R.lmax));
}

void pushup(int p) 
{
    PushUp(tr[p], tr[p << 1], tr[p << 1 | 1]);
}

void build(int p, int l, int r) 
{
    tr[p].l = l, tr[p].r = r;
    if (l == r) return void(tr[p] = {l, r, a[l], a[l], a[l], a[l]});
    
    int mid = l + r >> 1;
    build(p << 1, l, mid), build(p << 1 | 1, mid + 1, r);
    pushup(p);
}

void modify(int p, int x, int v) 
{
    int l = tr[p].l, r = tr[p].r;
    if (l == x && r == x) return void(tr[p] = {l, r, v, v, v, v});
    
    int mid = l + r >> 1;
    if (x <= mid) modify(p << 1, x, v);
    else modify(p << 1 | 1, x, v);
    pushup(p);
}

Seg query(int p, int l, int r) 
{
    if (tr[p].l >= l && tr[p].r <= r) return tr[p];
    
    int mid = tr[p].l + tr[p].r >> 1;
    if (l > mid) return query(p << 1 | 1, l, r);
    if (r <= mid) return query(p << 1, l, r);
        
    Seg L = query(p << 1, l, r);
    Seg R = query(p << 1 | 1, l, r);
    
    Seg res;
    PushUp(res, L, R);
    return res;
}

int main() 
{
    scanf("%d%d", &n, &m);
    
    for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
    
    build(1, 1, n);
    
    while (m -- ) 
    {
        int k, x, y;
        scanf("%d%d%d", &k, &x, &y);
        if (k == 1) printf("%d\n", query(1, min(x, y), max(x, y)).v);
        else modify(1, x, y);
    }
    
    return 0;
}

标签:AcWing245,半边,子段,int,qquad,回答,问题,情况,区间
From: https://www.cnblogs.com/StkOvflow/p/17011461.html

相关文章

  • #yyds干货盘点#nodejs 后端 token 权限问题
    话不多说,直接上代码登录接口exportdefaultclassAuthController{staticasynclogin(req,res){try{const{name,password}=req.body;if(!nam......
  • 微信小程序中data里的正则表达式丢失问题
    最近在开发微信小程序的时候在data里面定义了正则表达式,结果在读取的时候发现正则表达式丢了。只返回了一个空的对象Page({data:{reg:/^1\d{10}$/g},onLo......
  • vue中 WebSocket connection to 'ws://192.168.10.103:8080/ws' failed 问题的解决
    首先吧 vue中WebSocketconnectionto'ws://192.168.10.103:8080/ws'failed这个报错它不会影响你代码的运行,但是报错一定程度上影响页面的美观度。   下面我们......
  • 算法--旅行者过河问题
    1.题目在漆黑的夜里,四位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,四个人一共只带了一只手电筒,而桥窄得只够......
  • gitbook安装报错:解决卡顿在 Installing GitBook 3.2.3 的问题
    根据网上的教程安装gitbook,一直卡顿在installinggitbook3.2.3的页面建议先看完全文,再进行尝试正常的安装教程安装nvm————npm版本控制器,地址:点我在安装nvm时有两......
  • Spring 多数据源事务配置问题
    在SpringSide3中,白衣提供的预先配置好的环境非常有利于用户进行快速开发,但是同时也会为扩展带来一些困难。最直接的例子就是关于在项目中使用多个数据源的问题,似乎很难搞......
  • antv/g2图形y轴混乱问题
    antv/g2中柱状图y轴数据混乱,原因:后台返回的数据是字符串,图上需要的是数字类型。 比如图一,一开始接到的数据是字符串类型,改为数字类型后就正常展示了,图二。 图一 ......
  • 关于 已分配的DHCP租约 时间问题
    现在刷的固件默认的DHCP租约  时间12小时,对于家用路由来说明显还是太短了,请问怎么设置更长些? 看看/etc/config/dhcp文件,里面有一段configdhcp'lan'optioninter......
  • MD5安全吗,MD5加密有哪些问题,如何提高安全性?
    MD5是一种散列函数,在计算机安全领域得到广泛应用。然而,MD5国际密码算法被王小云研究团队证实并不安全,因为MD5本身存在一些缺点,这些缺点导致了MD5并不是很安全,可能会带来信息......
  • 解决二进制文件下载乱码问题
    好久没写博客了,突然想记录点什么。前段时间遇到一个问题,记录一下,以后遇到可以找到解决方案。事情的原由是这样的,后端返回一个二进制的csv文件让前端进行下载,前端采用axio......