《P1253 扶蘇的問題》

題目描述

給定一個長度為?n?的序列?a,要求支持如下三個操作:

  1. 給定區間?[l,r],將區間內每個數都修改為?x。
  2. 給定區間?[l,r],將區間內每個數都加上?x。
  3. 給定區間?[l,r],求區間內的最大值。

輸入格式

第一行是兩個整數,依次表示序列的長度?n?和操作的個數?q。
第二行有?n?個整數,第?i?個整數表示序列中的第?i?個數?ai?。
接下來?q?行,每行表示一個操作。每行首先有一個整數?op,表示操作的類型。

  • 若?op=1,則接下來有三個整數?l,r,x,表示將區間?[l,r]?內的每個數都修改為?x。
  • 若?op=2,則接下來有三個整數?l,r,x,表示將區間?[l,r]?內的每個數都加上?x。
  • 若?op=3,則接下來有兩個整數?l,r,表示查詢區間?[l,r]?內的最大值。

輸出格式

對于每個?op=3?的操作,輸出一行一個整數表示答案。

輸入輸出樣例

輸入 #1復制

6 6
1 1 4 5 1 4
1 1 2 6
2 3 4 2
3 1 4
3 2 3
1 1 6 -1
3 1 6

輸出 #1復制

7
6
-1

輸入 #2復制

4 4
10 4 -3 -7
1 1 3 0
2 3 4 -4
1 2 4 -9
3 1 4

輸出 #2復制

0

說明/提示

數據規模與約定

  • 對于?10%?的數據,n=q=1。
  • 對于?40%?的數據,n,q≤103。
  • 對于?50%?的數據,0≤ai?,x≤104。
  • 對于?60%?的數據,op=1。
  • 對于?90%?的數據,n,q≤105。
  • 對于?100%?的數據,1≤n,q≤106,1≤l,r≤n,op∈{1,2,3},∣ai?∣,∣x∣≤109。

提示

請注意大量數據讀入對程序效率造成的影響。

代碼實現:

#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;

typedef long long ll;

struct SegmentTreeNode {
? ? ll max_val;
? ? ll add;
? ? ll set;
? ? bool has_set;
};

class SegmentTree {
private:
? ? vector<SegmentTreeNode> tree;
? ? int n;
? ? vector<ll> arr;

? ? void build(int node, int start, int end) {
? ? ? ? tree[node].add = 0;
? ? ? ? tree[node].has_set = false;
? ? ? ? if (start == end) {
? ? ? ? ? ? tree[node].max_val = arr[start - 1];
? ? ? ? ? ? tree[node].set = arr[start - 1];
? ? ? ? } else {
? ? ? ? ? ? int mid = (start + end) / 2;
? ? ? ? ? ? build(2 * node, start, mid);
? ? ? ? ? ? build(2 * node + 1, mid + 1, end);
? ? ? ? ? ? tree[node].max_val = max(tree[2 * node].max_val, tree[2 * node + 1].max_val);
? ? ? ? }
? ? }

? ? void push_down(int node, int start, int end) {
? ? ? ? int mid = (start + end) / 2;
? ? ? ? int left_node = 2 * node;
? ? ? ? int right_node = 2 * node + 1;

? ? ? ? if (tree[node].has_set) {
? ? ? ? ? ? tree[left_node].max_val = tree[node].set;
? ? ? ? ? ? tree[right_node].max_val = tree[node].set;
? ? ? ? ? ? tree[left_node].set = tree[node].set;
? ? ? ? ? ? tree[right_node].set = tree[node].set;
? ? ? ? ? ? tree[left_node].add = 0;
? ? ? ? ? ? tree[right_node].add = 0;
? ? ? ? ? ? tree[left_node].has_set = true;
? ? ? ? ? ? tree[right_node].has_set = true;
? ? ? ? ? ? tree[node].has_set = false;
? ? ? ? }

? ? ? ? if (tree[node].add != 0) {
? ? ? ? ? ? tree[left_node].max_val += tree[node].add;
? ? ? ? ? ? tree[right_node].max_val += tree[node].add;
? ? ? ? ? ? if (tree[left_node].has_set) {
? ? ? ? ? ? ? ? tree[left_node].set += tree[node].add;
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? tree[left_node].add += tree[node].add;
? ? ? ? ? ? }
? ? ? ? ? ? if (tree[right_node].has_set) {
? ? ? ? ? ? ? ? tree[right_node].set += tree[node].add;
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? tree[right_node].add += tree[node].add;
? ? ? ? ? ? }
? ? ? ? ? ? tree[node].add = 0;
? ? ? ? }
? ? }

? ? void update_set(int node, int start, int end, int l, int r, ll x) {
? ? ? ? if (r < start || l > end) {
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? if (l <= start && end <= r) {
? ? ? ? ? ? tree[node].max_val = x;
? ? ? ? ? ? tree[node].set = x;
? ? ? ? ? ? tree[node].add = 0;
? ? ? ? ? ? tree[node].has_set = true;
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? push_down(node, start, end);
? ? ? ? int mid = (start + end) / 2;
? ? ? ? update_set(2 * node, start, mid, l, r, x);
? ? ? ? update_set(2 * node + 1, mid + 1, end, l, r, x);
? ? ? ? tree[node].max_val = max(tree[2 * node].max_val, tree[2 * node + 1].max_val);
? ? }

? ? void update_add(int node, int start, int end, int l, int r, ll x) {
? ? ? ? if (r < start || l > end) {
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? if (l <= start && end <= r) {
? ? ? ? ? ? tree[node].max_val += x;
? ? ? ? ? ? if (tree[node].has_set) {
? ? ? ? ? ? ? ? tree[node].set += x;
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? tree[node].add += x;
? ? ? ? ? ? }
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? push_down(node, start, end);
? ? ? ? int mid = (start + end) / 2;
? ? ? ? update_add(2 * node, start, mid, l, r, x);
? ? ? ? update_add(2 * node + 1, mid + 1, end, l, r, x);
? ? ? ? tree[node].max_val = max(tree[2 * node].max_val, tree[2 * node + 1].max_val);
? ? }

? ? ll query_max(int node, int start, int end, int l, int r) {
? ? ? ? if (r < start || l > end) {
? ? ? ? ? ? return LLONG_MIN;
? ? ? ? }
? ? ? ? if (l <= start && end <= r) {
? ? ? ? ? ? return tree[node].max_val;
? ? ? ? }
? ? ? ? push_down(node, start, end);
? ? ? ? int mid = (start + end) / 2;
? ? ? ? ll left_max = query_max(2 * node, start, mid, l, r);
? ? ? ? ll right_max = query_max(2 * node + 1, mid + 1, end, l, r);
? ? ? ? return max(left_max, right_max);
? ? }

public:
? ? SegmentTree(const vector<ll>& a) {
? ? ? ? arr = a;
? ? ? ? n = arr.size();
? ? ? ? tree.resize(4 * n);
? ? ? ? build(1, 1, n);
? ? }

? ? void set_range(int l, int r, ll x) {
? ? ? ? update_set(1, 1, n, l, r, x);
? ? }

? ? void add_range(int l, int r, ll x) {
? ? ? ? update_add(1, 1, n, l, r, x);
? ? }

? ? ll get_max(int l, int r) {
? ? ? ? return query_max(1, 1, n, l, r);
? ? }
};

int main() {
? ? ios_base::sync_with_stdio(false);
? ? cin.tie(NULL);

? ? int n, q;
? ? cin >> n >> q;

? ? vector<ll> a(n);
? ? for (int i = 0; i < n; ++i) {
? ? ? ? cin >> a[i];
? ? }

? ? SegmentTree st(a);

? ? for (int i = 0; i < q; ++i) {
? ? ? ? int op;
? ? ? ? cin >> op;
? ? ? ? if (op == 1) {
? ? ? ? ? ? int l, r;
? ? ? ? ? ? ll x;
? ? ? ? ? ? cin >> l >> r >> x;
? ? ? ? ? ? st.set_range(l, r, x);
? ? ? ? } else if (op == 2) {
? ? ? ? ? ? int l, r;
? ? ? ? ? ? ll x;
? ? ? ? ? ? cin >> l >> r >> x;
? ? ? ? ? ? st.add_range(l, r, x);
? ? ? ? } else if (op == 3) {
? ? ? ? ? ? int l, r;
? ? ? ? ? ? cin >> l >> r;
? ? ? ? ? ? cout << st.get_max(l, r) << endl;
? ? ? ? }
? ? }

? ? return 0;
} ? ?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/86186.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/86186.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/86186.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

09.【C語言學習筆記】指針(一)

目錄 1. 內存和地址 1.1 內存 1.2 究竟該如何理解編址 2. 指針變量和地址 2.1 取地址操作符&#xff08;&&#xff09; 2.2 指針變量和解引用操作符&#xff08;*&#xff09; 2.2.1 指針變量 2.2.2 如何拆解指針類型 2.2.3 解引用操作符 * 2.3 指針變量的大小…

Java中static關鍵字的作用與使用詳解

static是Java中一個非常重要的關鍵字&#xff0c;它可以用來修飾變量、方法、代碼塊和嵌套類。下面將從多個方面詳細解釋static的作用和使用方法。 一、static變量&#xff08;類變量&#xff09; 作用 static變量屬于類&#xff0c;而不是類的某個實例。所有實例共享同一個s…

HMLDM-UD100A 型工業激光測距儀通過modbusRTU 轉 profinet 網關輕松接入到西門子1200plc

HMLDM-UD100A 型工業激光測距儀通過modbusRTU 轉 profinet 網關輕松接入到西門子1200plc 在現代工業生產與自動化控制領域&#xff0c;精準的測量設備與高效的通信技術至關重要。HMLDM-UD100A 型工業激光測距儀憑借其高精度、穩定性強等優勢&#xff0c;廣泛應用于各類工業場景…

數據結構與算法:圖論——深度優先搜索dfs

深度優先搜索dfs 提到深度優先搜索&#xff08;dfs&#xff09;&#xff0c;就不得不說和廣度優先搜索&#xff08;bfs&#xff09;有什么區別 根據搜索方式的不同&#xff0c;可以將圖的遍歷分為「深度優先搜索」和「廣度優先搜索」。 深度優先搜索&#xff1a;從某一頂點出…

數組題解——?合并區間【LeetCode】

56. 合并區間 排序&#xff1a; 將所有區間按起始位置 start 從小到大排序。這樣&#xff0c;重疊的區間會相鄰排列&#xff0c;方便后續合并。 合并&#xff1a; 初始化一個空列表 merged&#xff0c;用于存儲合并后的區間。遍歷排序后的區間列表&#xff1a; 如果 merged 為…

關于高精度和鏈表的詳細講解(從屬于GESP五級)

本章內容 高精度 鏈表 位數再多&#xff0c;只管穩穩進位&#xff0c;終會把答案寫滿。 一、高精度 1. 什么是高精度 ? 定義 “高精度整數”指不受 C 原生整型 (int / long long) 位寬限制&#xff0c;而用數組模擬任意位數的大整數。 ? 必要性 64 位 long long 僅能…

Python自動化框架選型指南:Selenium/Airflow/Celery該選誰?

在Python自動化領域,Selenium、Airflow和Celery是三個高頻出現的工具,但它們的定位和適用場景截然不同。許多開發者在技術選型時容易混淆它們的邊界,導致項目架構臃腫或功能不匹配。本文將通過對比分析,幫你明確不同場景下的最佳選擇。 一、框架定位與核心功能對比 框架核…

50天50個小項目 (Vue3 + Tailwindcss V4) ? | DrinkWater(喝水記錄組件)

&#x1f4c5; 我們繼續 50 個小項目挑戰&#xff01;—— DrinkWater組件 倉庫地址&#xff1a;https://github.com/SunACong/50-vue-projects 項目預覽地址&#xff1a;https://50-vue-projects.vercel.app/ 使用 Vue 3 的 Composition API 和 <script setup> 語法結…

UAVAI-YOLO:無人機航拍圖像的小目標檢測模型

摘要 針對無人機航拍圖像目標檢測效果差的問題&#xff0c;提出改進的UAVAI-YOLO模型。首先&#xff0c;為使模型獲得更加豐富的語義信息&#xff0c;使用改進可變形卷積網絡&#xff08;deformable convolutional networks&#xff0c;DCN&#xff09;替換原骨干&#xff08…

Solidity 入門教程(一):Hello Web3,從一個字符串開始!

學習 Solidity 最好的方式&#xff0c;就是寫出你的第一個合約&#xff01;在本篇文章中&#xff0c;我們將用極簡的代碼&#xff0c;通過 Remix 平臺快速實現并運行一個 “Hello Web3!” 合約&#xff0c;正式邁入智能合約開發的大門。 一、什么是 Solidity&#xff1f; Sol…

串擾與包地

串擾與包地&#xff1a; 串擾與包地一直是業界非常關心的一個問題&#xff0c;圍繞著它們的爭論非常多&#xff0c;那到底是包地好 還是不包地好呢?高速先生嘗試著從理論和實際測試上來給大家做一個分析。 為了驗證它&#xff0c;高速先生做了以下幾種情況&#xff0c;如圖5-…

leetcode hot 100之:二叉樹的最近公共祖先

本來不打算寫的哈哈哈但是發現這一道遞歸我是有思路的&#xff01;&#xff01;自己能想到一些方向&#xff01;我真棒&#xff01;所以記錄一下哈哈哈 我的思路&#xff1a; 1、祖先一定是自身或往上找&#xff0c;所以如何逆著走呢&#xff1f; 2、3種情況&#xff1a; 有…

【VUE】某時間某空間占用情況效果展示,vue2+element ui實現。場景:會議室占用、教室占用等。

某時間某空間占用情況效果展示&#xff0c;vue2element ui實現。場景&#xff1a;會議室占用、教室占用等。 場景說明&#xff1a; 現在需要基于vue2和el-table實現每日會議室個時間點占用情況。 已知數據&#xff1a; 1、會議室數據&#xff08;名稱&#xff0c;id&#xff…

Git更換源方式記錄

本文首發地址&#xff1a;https://www.dawnsite.cn/archives/198.html 該方式前提是本地項目已關聯遠程倉庫&#xff0c;由于業務變更git地址改變 1. 移除本地已有遠程倉庫 git remote remove origin2. 添加新的遠程倉庫源 git remote add origin "clone地址"3.一步…

前端面試專欄-主流框架:12. Vue3響應式原理與API

&#x1f525; 歡迎來到前端面試通關指南專欄&#xff01;從js精講到框架到實戰&#xff0c;漸進系統化學習&#xff0c;堅持解鎖新技能&#xff0c;祝你輕松拿下心儀offer。 前端面試通關指南專欄主頁 前端面試專欄規劃詳情 Vue3響應式原理與API詳解 一、引言 Vue3作為Vue.j…

DAY 37 早停策略和模型權重的保存

早停策略 import torch.nn as nn import torch.optim as optim import time import matplotlib.pyplot as plt from tqdm import tqdm# Define the MLP model class MLP(nn.Module):def __init__(self):super(MLP, self).__init__()self.fc1 nn.Linear(X_train.shape[1], 10)s…

零基礎搭建Spring AI本地開發環境指南

Spring AI 是一個 Spring 官方團隊主導的開源項目&#xff0c;旨在將生成式人工智能&#xff08;Generative AI&#xff09;能力無縫集成到 Spring 應用程序中。它提供了一個統一的、Spring 風格的抽象層&#xff0c;簡化了與各種大型語言模型&#xff08;LLMs&#xff09;、嵌…

windows登錄系統配置雙因子認證的解決方案

在數字化浪潮席卷全球的今天&#xff0c;安全如同氧氣般不可或缺。Verizon《2023年數據泄露調查報告》指出&#xff0c;80%的黑客攻擊與登錄憑證失竊直接相關。當傳統密碼防護變得千瘡百孔&#xff0c;企業如何在身份驗證的戰場上贏得主動權&#xff1f;答案就藏在"雙保險…

Java數據結構——線性表Ⅱ

一、鏈式存儲結構概述 1. 基本概念&#xff08;邏輯分析&#xff09; 核心思想&#xff1a;用指針將離散的存儲單元串聯成邏輯上連續的線性表 設計動機&#xff1a;解決順序表 "預先分配空間" 與 "動態擴展" 的矛盾 關鍵特性&#xff1a; 結點空間動態…

技術基石:SpreadJS 引擎賦能極致體驗

在能源行業數字化轉型的浪潮中&#xff0c;青島國瑞信息技術有限公司始終以技術創新為核心驅動力&#xff0c;不斷探索前沿技術在能源領域的深度應用。其推出的 RCV 行列視生產數據應用系統之所以能夠在行業內脫穎而出&#xff0c;離不開背后強大的技術基石 ——SpreadJS 引擎。…