题意不用解释了
线段树:
#include <cstdio> #include <algorithm> using namespace std; #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 const int maxn = 222222; int MAX[maxn<<2]; void PushUP(int rt) { MAX[rt] = max(MAX[rt<<1] , MAX[rt<<1|1]); } void build(int l,int r,int rt) { if (l == r) { scanf("%d",&MAX[rt]); return ; } int m = (l + r) >> 1; build(lson); build(rson); PushUP(rt); } void update(int p,int add,int l,int r,int rt) { if (l == r) { MAX[rt] = add; return ; } int m = (l + r) >> 1; if (p <= m) update(p , add , lson); else update(p , add , rson); PushUP(rt); } int query(int L,int R,int l,int r,int rt) { if (L <= l && r <= R) { return MAX[rt]; } int m = (l + r) >> 1; int ret = 0; //递归调用每回求最值 if (L <= m) ret = max(ret , query(L , R , lson)); if (R > m) ret = max(ret , query(L , R , rson)); return ret; } int main() { int n , m; while (~scanf("%d%d",&n,&m)) { build(1 , n , 1); while (m --) { char op[2]; int a , b; scanf("%s%d%d",op,&a,&b);//此处用%s 避免一个字符错误 if (op[0] == 'Q') printf("%d\n",query(a , b , 1 , n , 1)); else update(a , b , 1 , n , 1); } } return 0; }
树状数组
#include<iostream> #include<cstring> #include <cstring> #define N 200001 using namespace std; int num[N],p[N]; int n; int lowbit(int t) { return t&(-t); } void change()//找最大值初始化 { int i,j; for(i = 1;i <= n;i ++) { p[i] = num[i]; for(j = 1;j < lowbit(i);j <<= 1) //找比i小的数但又在lowbit(i)+1到i这个区间上的数更新p数组 { p[i]=max(p[i],p[i-j]);//j是以2倍的速度增长 } } } void insert(int t,int sore) { num[t] = sore; while(t <= n) { if(sore > p[t]) p[t] = sore; else break; t += lowbit(t); } } int getmax(int l,int r)//找最大值 { int ans = num[r]; for(;;) { ans=max(ans,num[r]);//跟r位置上的数字比较 if(l == r) break; for(r = r-1;r-l >=lowbit(r);r -= lowbit(r)) { if(ans < p[r]) ans = p[r]; } }//r自减1,判断r-lowbit(r)和l之间的关系如果l在区间内就不能减了而是继续循环 return ans;//如果l比r-lowbit(r)小的话,就可以之间判断ans和p[r]的最值了。 } int main() { int m,i,id,sd,max; char str[2]; while(scanf("%d%d",&n,&m)!=EOF) { memset(p,0,sizeof(p)); for(i = 1;i <= n;i ++) scanf("%d",&num[i]); //scanf("%d%*c",&num[i]); //若此处是这个%*c是为了消除后面的回车字符,后面就可以改为输入一个字符 change(); for(i = 1;i <= m;i ++) { scanf("%s%d%d%*c",str,&id,&sd); if(str[0] == 'Q') { max = getmax(id,sd); printf("%d\n",max); } else if(str[0] == 'U') { insert(id,sd); } } } return 0; }