题意:
分析:
/* 线段树一般也就两种写法: 1、传统递归建树的开2N-1即可。 2、按照堆结构非递归建树,要开2^([logN]+1),[]表示取上整。 至于为什么有一说要开4N,其实这也是上述第二种情况,因为2^([logN]+1)在最坏情况下接近4N。 比如N=1024时只用开2048,而N=1025时却需要开4096个节点,为3.99N。 但在大多数情况下远达不到4N,所以建议还是手动计算出使用大小。 */
//AC CODE:
#include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int maxn = 222222; int sum[maxn<<2]; void PushUP(int rt) { sum[rt] = max(sum[rt<<1],sum[rt<<1|1]); } void build(int l,int r,int rt) { if (l == r) { scanf("%d",&sum[rt]); return ; } int m = (l + r) >> 1; build(l , m , rt << 1); build(m + 1 , r , rt << 1 | 1); PushUP(rt); } void update(int p,int add,int l,int r,int rt) { if (l == r) { sum[rt] = add; return ; } int m = (l + r) >> 1; if (p <= m) update(p , add , l , m , rt << 1); else update(p , add , m + 1 , r , rt << 1 | 1); PushUP(rt); } int query(int L,int R,int l,int r,int rt) { if (L <= l && r <= R) { return sum[rt]; } int m = (l + r) >> 1; int ret = -1; if (L <= m) ret = max(ret,query(L , R , l , m , rt << 1)); if (R > m) ret = max(ret,query(L , R , m + 1 , r , rt << 1 | 1)); return ret; } int main() { int n,m,a,b; while(scanf("%d %d",&n,&m)!=EOF) { build(1 , n , 1); char op[2]; while (m--) { scanf("%s %d %d",op,&a,&b); if (op[0] == 'Q') printf("%d\n",query(a , b , 1 , n , 1)); else update(a , b , 1 , n , 1); } } return 0; }
//TLE CODE:
#include <cstdio> using namespace std; const int maxn = 222222; int sum[maxn<<2]; void PushUP(int rt) { sum[rt] = sum[rt<<1] > sum[rt<<1|1] ? sum[rt<<1] : sum[rt<<1|1]; } void build(int l,int r,int rt) { if (l == r) { scanf("%d",&sum[rt]); return ; } int m = (l + r) >> 1; build(l , m , rt << 1); build(m + 1 , r , rt << 1 | 1); PushUP(rt); } void update(int p,int add,int l,int r,int rt) { if (l == r) { sum[rt] = add; return ; } int m = (l + r) >> 1; if (p <= m) update(p , add , l , m , rt << 1); else update(p , add , m + 1 , r , rt << 1 | 1); PushUP(rt); } int query(int L,int R,int l,int r,int rt) { if (L <= l && r <= R) { return sum[rt]; } int m = (l + r) >> 1; int ret = -1; if (L <= m) ret = ret>query(L , R , l , m , rt << 1)?ret:query(L , R , l , m , rt << 1); if (R > m) ret = ret>query(L , R , m + 1 , r , rt << 1 | 1)?ret:query(L , R , m + 1 , r , rt << 1 | 1); return ret; } int main() { int n,m,a,b; while(scanf("%d %d",&n,&m)!=EOF) { build(1 , n , 1); char op[2]; while (m--) { scanf("%s %d %d",op,&a,&b); if (op[0] == 'Q') printf("%d\n",query(a , b , 1 , n , 1)); else update(a , b , 1 , n , 1); } } return 0; }