首页 > 其他分享 >C. 【例题3】公园遛狗

C. 【例题3】公园遛狗

时间:2023-08-18 15:55:05浏览次数:46  
标签:遛狗 int max sum 公园 tr ans maxright 例题

C. 【例题3】公园遛狗

我们对于每一个线段树的节点,维护几个值

\(sum\) 表示当前区间的区间和

\(ml\) 表示最大前缀和

\(mr\) 表示最大后缀和

\(ans\) 表示当前区间的最大子段和

接下来我们来判断如何上传答案

首先假定 \(tr_{ls}\) 和 \(tr_{rs}\) 已经做好了,然后考虑合并成 \(tr_p\) 的值

首先 \(tr_p.sum=tr_{ls}.sum+tr_{rs}.sum\) 这个就是直接合并大区间

然后 \(tr_p.ml=\max(tr_{ls}.ml,tr_{ls}.sum+tr_{rs}.ml)\)

\(tr_p.mr=\max(tr_{rs}.mr,tr_{rs}.sum+tr_{ls}.ml)\)

这个自行对照画图

\(tr_p.ans=\max(\max(tr_{ls}.ans,tr_{rs}.ans),tr_{ls}.mr+tr_{rs}.ml)\)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e6 + 10;

int n, m;
struct node
{
    int l, r;
    ll maxleft, maxright, sum, ans;
} tr[N];

void pushon(int p)
{
    tr[p].sum = tr[p * 2].sum + tr[p * 2 + 1].sum;
    tr[p].maxleft = max(tr[p * 2].maxleft, tr[p * 2].sum + tr[p * 2 + 1].maxleft);
    tr[p].maxright = max(tr[p * 2 + 1].maxright, tr[p * 2 + 1].sum + tr[p * 2].maxright);
    tr[p].ans = max(max(tr[p * 2].ans, tr[p * 2 + 1].ans), tr[p * 2].maxright + tr[p * 2 + 1].maxleft);
}

void build(int p, int l, int r)
{
    tr[p].l = l, tr[p].r = r;
    if (l == r)
    {
        cin >> tr[p].sum;
        tr[p].maxleft = tr[p].maxright = tr[p].ans = tr[p].sum;
        return;
    }
    int mid = (l + r) >> 1;
    build(p * 2, l, mid);
    build(p * 2 + 1, mid + 1, r);
    pushon(p);
}

node ask(int p, int ql, int qr)
{
    if (ql <= tr[p].l && tr[p].r <= qr)
        return tr[p];
    int mid = (tr[p].l + tr[p].r) >> 1;
    if (qr <= mid)
        return ask(p * 2, ql, qr);
    else
    {
        if (ql > mid)
            return ask(p * 2 + 1, ql, qr);
        node t, a = ask(p * 2, ql, qr), b = ask(p * 2 + 1, ql, qr);
        t.maxleft = max(a.maxleft, a.sum + b.maxleft);
        t.maxright = max(b.maxright, a.maxright + b.sum);
        t.ans = max(max(a.ans, b.ans), a.maxright + b.maxleft);
        return t;
    }
}

void update(int p, int a, int x)
{
    if (tr[p].l == tr[p].r)
    {
        tr[p].maxleft = tr[p].maxright = tr[p].ans = tr[p].sum = x;
        return;
    }
    int mid = (tr[p].l + tr[p].r) >> 1;
    if (a <= mid)
        update(p * 2, a, x);
    else
        update(p * 2 + 1, a, x);
    pushon(p);
}

int main()
{
    cin >> n >> m;
    build(1, 1, n);
    while (m--)
    {
        int opt, x, y;
        cin >> opt >> x >> y;
        if (opt == 1)
        {
            if (x > y)
                swap(x, y);
            cout << ask(1, x, y).ans << endl;
        }
        else
            update(1, x, y);
    }
    return 0;
}

标签:遛狗,int,max,sum,公园,tr,ans,maxright,例题
From: https://www.cnblogs.com/ljfyyds/p/17640725.html

相关文章

  • 东莞河边公园装饰喷漆不锈钢编织花朵雕塑厂家报价
    东莞河边公园装饰喷漆不锈钢编织花朵雕塑厂家报价人们常常用花朵来形容美好的事物,而每种花朵也有其各自独特的寓意,栽种在家中可以带来好运以及福气,营造出一种热闹喜庆的氛围,日常也可将其赠送给亲朋好友,表达出自己的美好祝愿。我们都知道,玫瑰花代表爱情,康乃馨代表母爱等等。人们都喜......
  • 凸包和凸组合例题
    https://codeforces.com/gym/467720/attachmentsM题网上博客https://blog.csdn.net/weixin_34284188/article/details/94669467我们最终线性组合的点一定会落在凸包内部,我们的答案就是凸包的上,右边界的点,包括端点,也包括凸包边上的点求凸包边上的点的横纵坐标积的最大值,是列......
  • 尺取法例题C++
    一、反向扫描(1)、判断回文串boolcheck(string&s,intleft,intright){inti=left,j=right;while(i<j){if(s[i]!=s[j]){returnfalse;}i++;j--;......
  • Tarjan 例题:洛谷P1407 [国家集训队] 稳定婚姻
    在洛谷中查看题意:自己读一下,大致就是\(2n\)个点,每个点编号为\(1-2n\),\(\lfloor编号/2\rfloor\)相同的点连条边。然后再给\(m\)条边。问:将每个\(\lfloor编号/2\rfloor\)相同的点间连的边断开,还能不能使每个编号为奇数的点都有一个编号为偶数的点对应。这个......
  • 递推算法例题C++
    1、移动路线【题目描述】X桌子上有一个m行n列的方格矩阵,将每个方格用坐标表示,行坐标从下到上依次递增,列坐标从左至右依次递增,左下角方格的坐标为(1,1),则右上角方格的坐标为(m,n)。小明是个调皮的孩子,一天他捉来一只蚂蚁,不小心把蚂蚁的右脚弄伤了,于是蚂蚁只能向上或向右移动。小明......
  • 浙江休闲公园装饰镜面不锈钢七彩狗雕塑厂家报价
    浙江休闲公园装饰镜面不锈钢七彩狗雕塑厂家报价不锈钢七彩狗雕塑 让形说话,让形表达情感!这么可爱的造型雕塑,不管大人还是小朋友都会很喜欢。不锈钢七彩狗雕塑 可用于公园、商场、广场、当成摆件座椅,时尚又实用,是美化空间的好帮手!......
  • c++算法之离散化例题
    离散化基础2题目描述给定 n 个元素的数列,将相同的数据离散化为一个数据(去重),即把 {4000,201,11,45,11}{4000,201,11,45,11} 离散化为 {4,3,1,2,1}{4,3,1,2,1}。输入格式第一行一个整数 (1≤m≤105)n(1≤n≤105),为元素的个数。第二行 n 个用空格隔天的整数a[i](−109......
  • PHP反序列化例题以及Bypass总结
    unseping题目源码<?phphighlight_file(__FILE__);classease{private$method;private$args;function__construct($method,$args){$this->method=$method;$this->args=$args;}function__destruct(){......
  • 信奥赛例题——1132,1166,1167,1186
    //1132//#include<iostream>//usingnamespacestd;//intmain(intargc,char**argv){// intN;// cin>>N;// stringS1,S2;// stringx="Rock",y="Scissors",z="Paper";// for(inti=0;i<N;i++){// cin>&g......
  • 【暑假例题】20230727 矩阵基本运算(C++)
    题目请使用C++实现矩阵的各种运算矩阵创建矩阵相加矩阵相减矩阵相乘数字乘矩阵矩阵上叠加矩阵左右叠加矩阵转置矩阵旋转矩阵求逆矩阵输出题目分析矩阵创建这里只需注意由于我们需要通过不同的函数对数组进行操作,所以我们需要将数组存储在容器或者使用指针防止数......