hdu1754 求区间最值 线段树 树状数组

来源:互联网 发布:蜻蜓fm 安卓网络错误 编辑:程序博客网 时间:2024/05/18 02:44

题意不用解释了

线段树:

#include <cstdio>#include <algorithm>using namespace std; #define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1const 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 200001using 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;}


 

原创粉丝点击