线段树单点更新 区间查询
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int maxn = 100000 + 7;
const int INF = ~0U >> 1;
struct node {
int left, right;
int val;
}str[maxn*5];
int n, q;
int a[maxn];
int BuildTree(int root, int left, int right) {
str[root].left = left;
str[root].right = right;
if(left == right) {
str[root].val = a[left];
return a[left];
}
int mid = (left + right) / 2;
int x = BuildTree(root*2, left, mid);
int y = BuildTree(root*2+1, mid + 1, right);
return str[root].val = min(x, y);
}
int Update(int root, int id, int val) {
if(str[root].left == str[root].right && str[root].left == id) {
a[id] = val;
str[root].val = val;
return val;
}
if(str[root].left > id || str[root].right < id) return str[root].val;
int mid = (str[root].left + str[root].right) / 2;
int x = Update(root*2, id, val);
int y = Update(root*2+1, id, val);
return str[root].val = min(x, y);
}
int Query(int root, int left, int right) {
if(str[root].left >= left && str[root].right <= right) return str[root].val;
if(str[root].left > right || str[root].right < left) return INF;
int x = Query(root*2, left, right);
int y = Query(root*2+1, left, right);
return min(x, y);
}
int main() {
scanf("%d%d", &n, &q);
for(int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
BuildTree(1, 1, n);
char que[37] = {0};
for(int i = 0; i < q; ++i) {
scanf("%s", que);
if(que[0] == 'q') {
int e = 0;
while(que[e] < '0' || que[e] > '9') ++e;
int x = atoi(que + e);
while(que[e] >= '0' && que[e] <= '9') ++e;
int y = atoi(que + e + 1);
printf("%d\n", Query(1, x, y));
} else {
int b[37] = {0}, k = 0, e = 0;
while(que[e]) {
if(que[e] == ')') break;
while(que[e] < '0' || que[e] > '9') ++e;
int num = atoi(que + e);
b[k++] = num;
while(que[e] >= '0' && que[e] <= '9') ++e;
}
int t = b[0], u = a[t];
for(int i = 0; i < k - 1; ++i)
Update(1, b[i], a[b[i+1]]);
Update(1, b[k-1], u);
}
}
return 0;
}