类型:单点更新,线段树 / 树状数组
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; inline int Rint() {int x; scanf("%d", &x); return x;} #define MAXN 200002 //#define MAX(x, y) (x)>(y)? (x):(y) 用这个算MAX(ret, query(L, R, a[e].mid+1, r, e<<1|1)),会超时,就因为多query了一次? struct node {int l, mid, r, v;}a[MAXN*4]; //v表示分数 int n, m; void pushUp(int e) { a[e].v=max(a[e<<1].v, a[e<<1|1].v); } void build(int l, int r, int e) { a[e].l=l, a[e].r=r; if(l==r) a[e].v=Rint(); else { a[e].mid=(l+r)>>1; build(l, a[e].mid, e<<1); build(a[e].mid+1, r, e<<1|1); pushUp(e); } } void update(int p, int b, int l, int r, int e) { if(l==r) { a[e].v = b; } else { if(p<=a[e].mid) update(p, b, l, a[e].mid, e<<1); else update(p, b, a[e].mid+1, r, e<<1|1); pushUp(e); } } int query(int L, int R, int l, int r, int e) { int ret=0; if(L<=l && r<=R) ret=a[e].v; //正常情况下总有一个等号成立 else // l L R r { if(L<=a[e].mid) ret = max(ret, query(L, R, l, a[e].mid, e<<1)); if(a[e].mid<R) ret = max(ret, query(L, R, a[e].mid+1, r, e<<1|1)); } return ret; } int main() { while(scanf("%d%d", &n, &m)!=EOF) { build(1, n, 1); char buf[10]; int a, b; while(m--) { scanf("%s%d%d", buf, &a, &b); if(buf[0]=='Q') printf("%d\n", query(a, b, 1, n, 1)); else update(a, b, 1, n, 1); } } }