记录一道线段树单点修改题目。
创建线段树的时间复杂度为O(n),每次查找和修改的时间复杂度均为O(logn)
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
int arr[maxn], tree[maxn], n, m;
void build(int node, int start, int end) {//构建线段树if (start == end) {tree[node] = arr[start];return;}int mid = start + (end - start) / 2;int left_node = 2 * node;int right_node = 2 * node + 1;build(left_node, start, mid);build(right_node, mid + 1, end);tree[node] = max(tree[left_node], tree[right_node]);
}
void Update(int node,int start,int end,int idx,int val) {//将下标idx的位置修改为valif (start == end) {if(arr[idx] < val){arr[idx] = val;tree[node] = val;}return;}int mid = start + (end - start) / 2;int left_node = node * 2;int right_node = node * 2 + 1;if (start <= idx && idx <= mid) {Update(left_node, start, mid, idx, val);}else {Update(right_node, mid + 1, end, idx, val);}tree[node] = max(tree[left_node], tree[right_node]);
}
int query(int node,int start,int end,int L,int R) {//寻找的区间是[L,R]if (start == L && end == R) return tree[node];if (R < start || end < L) return 0;if (start == end) return tree[node];int mid = start + (end - start) / 2;int left_node = node * 2;int right_node = node * 2 + 1;int L_max = query(left_node, start, mid, L, R);int R_max = query(right_node, mid + 1, end, L, R);return max(L_max, R_max);
}
int main() {cin >> n >> m;for (int i = 1; i <= n; i++) cin >> arr[i];build(1, 1, n);char c;int a, b;for (int i = 0; i < m; i++) {cin >> c >> a >> b;if (c == 'Q') cout << query(1, 1, n, a, b) << endl;else Update(1, 1, n, a, b);}return 0;
}