IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Codeforces 1649F 线段树 -> 正文阅读

[数据结构与算法]Codeforces 1649F 线段树

题意

传送门 Codeforces 1649F Serious Business

题解

枚举第一行的最右侧位置和最后一行的最左侧位置,将表达式分离变量可以得到
max ? 0 ≤ i ≤ j < n { f i + g i + c o s t ( i , j ) } \max\limits_{0\leq i\leq j<n}\{f_i+g_i+cost(i,j)\} 0ij<nmax?{fi?+gi?+cost(i,j)} 其中, s u m sum sum 为前缀和, c o s t ( i , j ) cost(i,j) cost(i,j) 为打通第二行 [ i , j ] [i,j] [i,j] 的花费,且 f i = s u m [ 0 ] [ i + 1 ] ? s u m [ 1 ] [ i ] , g i = s u m [ 1 ] [ i + 1 ] + s u m [ 2 ] [ n ] ? s u m [ 2 ] [ i ] f_i = sum[0][i+1]-sum[1][i], g_i = sum[1][i+1]+sum[2][n]-sum[2][i] fi?=sum[0][i+1]?sum[1][i],gi?=sum[1][i+1]+sum[2][n]?sum[2][i] 直接处理 c o s t ( i , j ) cost(i,j) cost(i,j) 较为困难,考虑将区间按照右界升序排序,依次枚举 q q q 个区间为所使用的最右侧区间。那么线段树维护 max ? 0 ≤ i ≤ j < n { f i ′ + g i } \max\limits_{0\leq i\leq j<n}\{f^{\prime}_i+g_i\} 0ij<nmax?{fi?+gi?} 即可,其中 f i ′ f^{\prime}_i fi? 代表 ( 0 , 0 ) ? ( 1 , i ) (0,0)\cdots (1,i) (0,0)?(1,i) 所需的花费,其中可能包含零个或多个区间,可以在查询的过程中更新。

max ? 0 ≤ i ≤ j < n { f i ′ + g i } \max\limits_{0\leq i\leq j<n}\{f^{\prime}_i+g_i\} 0ij<nmax?{fi?+gi?} 有两种维护思路,一种是查询时将 f , g f,g f,g 最大值递归至左右子区间进行查询;第二种考虑分治,即满足条件的 f , j f,j f,j 要么出现在左子区间或右子区间,要么由左子区间的最大 f f f 与右子区间的最大 g g g 构成。

总时间复杂度 O ( q log ? n ) O(q\log n) O(qlogn)

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
typedef long long ll;
const int MAXN = 5E5 + 5, SZ = 1 << 20;
struct seg
{
    int l, r, k;
    bool operator<(const seg &o) { return r < o.r; }
} ss[MAXN];
int N, Q, A[3][MAXN];
ll f[MAXN], g[MAXN], sum[3][MAXN];
struct node
{
#define f(v) tree[v].f
#define g(v) tree[v].g
#define mx(v) tree[v].mx
    ll f, g, mx;
    node operator+(node o)
    {
        node res;
        res.f = max(f, o.f), res.g = max(g, o.g);
        res.mx = max(max(mx, o.mx), f + o.g);
        return res;
    }
} tree[SZ];

void init(int k = 0, int l = 0, int r = N)
{
    if (r - l == 1)
    {
        f(k) = f[l], g(k) = g[l];
        mx(k) = f(k) + g(k);
        return;
    }
    int m = (l + r) / 2, chl = k * 2 + 1, chr = k * 2 + 2;
    init(chl, l, m), init(chr, m, r);
    tree[k] = tree[chl] + tree[chr];
}

void change(int a, int b, ll x, int k = 0, int l = 0, int r = N)
{
    if (r <= a || b <= l)
        return;
    if (a <= l && r <= b)
    {
        f(k) = max(f(k), x);
        mx(k) = f(k) + g(k);
        return;
    }
    int m = (l + r) / 2, chl = k * 2 + 1, chr = k * 2 + 2;
    change(a, b, x, chl, l, m), change(a, b, x, chr, m, r);
    tree[k] = tree[chl] + tree[chr];
}

node ask(int a, int b, int k = 0, int l = 0, int r = N)
{
    if (a <= l && r <= b)
        return tree[k];
    int m = (l + r) / 2, chl = k * 2 + 1, chr = k * 2 + 2;
    if (b <= m)
        return ask(a, b, chl, l, m);
    if (m <= a)
        return ask(a, b, chr, m, r);
    return ask(a, b, chl, l, m) + ask(a, b, chr, m, r);
}

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> N >> Q;
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < N; ++j)
            cin >> A[i][j], sum[i][j + 1] = sum[i][j] + A[i][j];
    for (int i = 0; i < N; ++i)
        f[i] = sum[0][i + 1] - sum[1][i], g[i] = sum[1][i + 1] + sum[2][N] - sum[2][i];
    for (int i = 0; i < Q; ++i)
    {
        auto &s = ss[i];
        cin >> s.l >> s.r >> s.k;
        --s.l;
    }
    sort(ss, ss + Q);
    init();
    ll res = LLONG_MIN;
    for (int i = 0; i < Q; ++i)
    {
        auto &s = ss[i];
        auto v = ask(s.l, s.r);
        res = max(res, v.mx - s.k);
        if (s.r < N)
            change(s.r, s.r + 1, v.f - s.k);
    }
    cout << res << '\n';
    return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:50:27  更:2022-03-15 22:53:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 13:26:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码