当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754
——>>线段树点修改,幸运,这次递归建树没有超时,437MS过!
#include <cstdio> #include <algorithm> using namespace std; const int maxn = 200000 + 10, INF = -214748364; int a[maxn], maxv[4*maxn], A, B; //a为输入数组,maxv为线段树结点数组,存该相应区间的最大值 void update(int o, int L, int R) //线段树更新,把a[A]改为B { if(L == R) maxv[o] = B; else { int M = L + (R - L) / 2; if(A <= M) update(2*o, L, M); else update(2*o+1, M+1, R); maxv[o] = max(maxv[2*o], maxv[2*o+1]); } } int query(int o, int L, int R) //线段树查询[A, B]间的最大值 { if(A <= L && R <= B) return maxv[o]; int M = L + (R - L) / 2, ans = INF; if(A <= M) ans = max(ans, query(2*o, L, M)); if(B > M) ans = max(ans, query(2*o+1, M+1, R)); return ans; } void build(int o, int L, int R) //建树 { if(L == R) { maxv[o] = a[L]; return; } int M = L + (R - L) / 2; if(L <= M) build(2*o, L, M); if(R > M) build(2*o+1, M+1, R); maxv[o] = max(maxv[2*o], maxv[2*o+1]); } int main() { int N, M; char C; while(~scanf("%d%d\n", &N, &M)) { for(int i = 1; i <= N; i++) scanf("%d", &a[i]); build(1, 1, N); while(M--) { scanf("\n%c%d%d", &C, &A, &B); if(C == 'U') update(1, 1, N); else printf("%d\n", query(1, 1, N)); } } return 0; }