杭电1754——线段树(单点更新)
杭电1754原题传送门
线段树单点更新详解传送门
写在最前面:用scanf(printf)代替cin(cout),时间少的不是一点点。同样的代码scanf能过,cin超时。嗯,玄学做题。
已过代码
# include <iostream>
# include <algorithm>
# include <cstdio>
# include <string>
using namespace std;
const int maxnn = int (1e5)*2;
struct str {
int l, r, n;
}s[maxnn*4];
void bulid(int l, int r, int k) {
s[k].l = l;
s[k].r = r;
s[k].n = 0;
if (l == r) {
return;
}
int mid = (l + r) / 2;
bulid(l, mid, 2 * k);
bulid(mid + 1, r, 2 * k + 1);
}
void insert(int d, int n, int k) {
if (s[k].l == d && d == s[k].r) {
s[k].n = n;
return;
}
int mid = (s[k].l + s[k].r) / 2;
if (d <= mid) {
insert(d, n, 2 * k);
}
else {
insert(d, n, 2 * k + 1);
}
s[k].n = max(s[k * 2].n, s[k * 2 + 1].n);
}
int maxn;
void fin(int l, int r, int k) {
if (s[k].l == l && s[k].r == r) {
maxn = max(maxn, s[k].n);
return;
}
int mid = (s[k].l + s[k].r) / 2;
if (r <= mid) {
fin(l, r, 2 * k);
}
else if (mid < l) {
fin(l, r, 2 * k + 1);
}
else {
fin(l, mid, 2 * k);
fin(mid+1,r, 2 * k+1);
}
}
int main() {
int n, m, x;
while (~scanf("%d%d",&n,&m)) {
bulid(1, n, 1);
for (int i = 0; i < n; i++) {
scanf ("%d",&x);
insert(i + 1, x, 1);
}
string s;
int a, b;
while (m--) {
cin >> s;
scanf("%d%d", &a, &b);
if (s[0] == 'U') {
insert(a, b, 1);
}
else if (s[0] == 'Q') {
maxn = 0;
fin(a, b, 1);
printf("%d\n", maxn);
}
}
}
return 0;
}