树状数组求区间最值 hdu 1754

原理:求和时c数组存的是相应区间的和,而在这c数组(mkx数组)求的是相应区间的最大值

#include <bits/stdc++.h>
using namespace std;
const int N = 400000+100;
int n,m,k,l,r;
int a[N];
int mkx[N],num[N];
char s[10];
int lowbit(int x)
{
    return x&(-x);
}
void init()
{
    for(int i=1;i<=n;i++)
    {
        mkx[i] = num[i];
        for(int j=1;j<lowbit(i);j*=2)
        {
           mkx[i] = max(mkx[i],mkx[i-j]);
        }
    }
    return ;
}
void update(int l,int val)
{
    num[l] = val;
    for(int i=l;i<=n;i+=lowbit(i))
    {
        mkx[i]=val;
        for(int j=1;j<lowbit(i);j*=2)
        {
            mkx[i] = max(mkx[i],mkx[i-j]);
        }
    }
    return ;
}
int query(int l,int r)
{
    int ans =  max(num[l],num[r]);
    while(true)
    {
        ans = max(ans, num[r]);
        if(l == r) break;
        r--;
        for(r;r-l>lowbit(r);r-=lowbit(r))
        {
            ans = max(ans,mkx[r]);
        }
    }
    return ans;
}
int main()
{
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        memset(num,0,sizeof(num));
        memset(mkx,0,sizeof(mkx));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&num[i]);
        }
        init();
        while(m--)
        {
            scanf("%s %d %d",s,&l,&r);
            if(s[0]=='U') update(l,r);
            else printf("%d\n",query(l,r));
        }
    }
    return 0;
}
 

猜你喜欢

转载自weiqingliu.iteye.com/blog/2253027
今日推荐