题意:
给定一段序列,更新某个点的值,查询某个区间的最大值;
思路:
首先,这个题的很好的做法应该是线段树,线段树是维护区间最值的很好的数据结构,
这里作为分块算法的入门题,学习一下;
分块 听说很牛逼,还有分块的思想也是很好的,是把问题根据某个条件分割,然后对某一部分进行暴力; 有点类似于哈希
对于这个题,更新和查询的复杂度都是 sqrt() 级别的,
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<set>
#include<queue>
#include<stack>
#include<map>
#define PI acos(-1.0)
#define in freopen("in.txt", "r", stdin)
#define out freopen("out.txt", "w", stdout)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 2e5 + 7, maxd = 500 + 7, mod = 1e9 + 7;
const int INF = 0x7f7f7f7f;
int n, m, q;
char s[3];
int a[maxn], id[maxn], max_[maxd];
void updata(int pos, int x) {
a[pos] = x;
int t = id[pos];
for(int i = (t-1)*m+1; i <= t*m; ++i)
max_[t] = max( max_[t], x );
}
int query(int l_, int r_) {
int ans = 0;
if(id[l_] == id[r_]) {
for(int i = l_; i <= r_; ++i)
ans = max( ans, a[i]);
}
else {
int t1 = id[l_]*m, t2 = (id[r_]-1)*m+1;
for(int i = l_; i <= t1; ++i)
ans = max( ans, a[i]);
for(int i = t2; i <= r_; ++i)
ans = max( ans, a[i]);
for(int i = id[l_]+1; i < id[r_]; ++i)
ans = max( ans, max_[i]);
}
return ans;
}
void init() {
memset(max_, 0, sizeof max_);
for(int i = 1; i <= n; ++i)
id[i] = (i-1) / m + 1;
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
for(int i = 1; i <= n; ++i)
max_[id[i]] = max( max_[id[i]], a[i]);
}
int main() {
while(~scanf("%d %d", &n, &q) && n) {
m = sqrt(n);
init();
for(int i = 0; i < q; ++i) {
int x, y;
scanf("%s %d %d", s, &x, &y);
if(s[0] == 'Q') {
printf("%d\n", query(x, y));
}
else updata(x, y);
}
}
return 0;
}