樣例輸入
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
這題我們需要維護的資訊,從區間的和變成了區間內的最大值。現在區間的內的某個值可能增大可能減小,若從上到下(從根到葉)進行節點更新,我們無法直接判斷目前區間內的最大的節點。
所以維護區間最大/最小值和維護區間和最大的不同就是:我們只能從下到上(從葉到根)進行節點更新。
1 #include<bits/stdc++.h> 2 using namespace std; 3 vector<int> maximum(200000 * 4); 4 void modify(int p, int left, int right, int x, int y){ 5 if (left == right) { 6 maximum[p] = y; //更新葉節點 7 return; 8 } 9 int mid = (left + right) / 2; 10 if (x <= mid) { 11 modify(p * 2, left, mid, x, y); 12 } else { 13 modify(p * 2 + 1, mid + 1, right, x, y); 14 } 15 maximum[p] = max(maximum[p * 2], maximum[p * 2 + 1]); //葉節點更新完成後再更新最大值 16 } 17 int query(int p, int left, int right, int x, int y){ 18 if (left >= x && right <= y){ 19 return maximum[p]; 20 } 21 int mid = (left + right) / 2, res, res1 = 0, res2 = 0; 22 if (x <= mid){ 23 res1 = query(p * 2, left, mid, x, y); 24 } 25 if (y > mid){ 26 res2 = query(p * 2 + 1, mid + 1, right, x, y); 27 } 28 return res = max(res1, res2); 29 } 30 int main(){ 31 int n, m; 32 cin >> n >> m; 33 int temp, x, y; 34 char operation; 35 for (int i = 1; i <= n; ++i) { 36 cin >> temp; 37 modify(1, 1, n, i, temp); 38 } 39 while (m--) { 40 cin >> operation >> x >> y; 41 if (operation == 'Q') { 42 cout << query(1, 1, n, x, y) << endl; 43 } else { 44 modify(1, 1, n, x, y); 45 } 46 } 47 }