計蒜客 - 最甜的蘋果
蒜頭君有很多蘋果,每個蘋果都有對應的甜度值。
蒜頭君現在想快速知道從第 個蘋果到第 個蘋果中,最甜的甜度值是多少。
因爲存放時間久了,有的蘋果會變甜,有的蘋果會因爲腐爛而變得不甜,所以蒜頭君有時候還需要修改第 個蘋果的甜度值。
輸入格式
第一行輸入兩個正整數 ,分別代表蘋果的個數和蒜頭君要進行的操作的數目。
每個蘋果從 到 進行編號。
接下來一行共有 個整數,分別代表這 個蘋果的初始甜度值。
接下來 行。每一行有一個字符 ,和兩個正整數 ,。
當 爲 Q
的時候,你需要輸出從 到 (包括 , )的蘋果當中,甜度值最高的蘋果的甜度值。
當 爲 U
的時候,你需要把蘋果 的甜度值更改爲 。
5 6
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5
輸出格式
在一行裏面輸出每次詢問的最高甜度值。
5
6
5
9
對模板稍作變形。
在修改操作的最後,將 s[p]
的值修改爲兩個孩子的最大值。
s[p] = max(s[p * 2], s[p * 2 + 1]);
在查詢過程中,始終以最大值作爲結果。
if (x <= mid) res = max(res, query(p * 2, l, mid, x, y));
if (y > mid) res = max(res, query(p * 2 + 1, mid + 1, r, x, y));
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 200000 * 3 + 7; // 由於還要 2 倍的父節點,所以乘以 3
int s[MAX_N] = {0};
int n = 0, m = 0;
// 修改
void modify(int p, int l, int r, int x, int v)
{
s[p] = v;
if (l == r) return; // 葉結點則退出
int mid = (l + r) / 2;
if (x <= mid) // 判斷 x 在左兒子還是右兒子
modify(p * 2, l, mid, x, v);
else
modify(p * 2 + 1, mid + 1, r, x, v);
s[p] = max(s[p * 2], s[p * 2 + 1]);
}
// 封裝後的修改,以供調用
void modify(int x, int v) {
modify(1, 1, n, x, v);
}
// 查詢
int query(int p, int l, int r, int x, int y)
{
if (x <= l && r <= y) return s[p]; // 若該結點被查詢區間包含
int mid = (l + r) / 2, res = 0;
if (x <= mid) res = max(res, query(p * 2, l, mid, x, y));
if (y > mid) res = max(res, query(p * 2 + 1, mid + 1, r, x, y));
return res;
}
// 封裝後的查詢,以供調用
int query(int x, int y) {
return query(1, 1, n, x, y);
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
int v;
scanf("%d", &v);
modify(i, v);
}
for (int i = 0; i < m; i++) {
char c;
scanf("\n%c", &c);
int x, y;
scanf("%d%d", &x, &y);
switch (c) {
case 'Q':
printf("%d\n", query(x, y));
break;
case 'U':
modify(x, y);
break;
default:
break;
}
}
return 0;
}
歡迎關注我的個人博客以閱讀更多優秀文章:凝神長老和他的朋友們(https://www.jxtxzzw.com)
也歡迎關注我的其他平臺:知乎( https://s.zzw.ink/zhihu )、知乎專欄( https://s.zzw.ink/zhuanlan )、嗶哩嗶哩( https://s.zzw.ink/blbl )、微信公衆號( 凝神長老和他的朋友們 )