HDU - 1754: I Hate It

题目链接:点击打开链接

题目大意:略。

解题思路:求最值类型的树状数组。

AC 代码

#include<bits/stdc++.h>
#include<cmath>

#define mem(a,b) memset(a,b,sizeof a);
#define INF 0x3f3f3f3f

using namespace std;

typedef long long ll;

const int maxn=200010;

int n,m;
int a[maxn], rs[maxn];

int lowbit(int x)
{
    return x & -x;
}

void update(int x,int val)
{
    a[x]=val;
    while(x<=n)
    {
        rs[x]=max(rs[x],val);
        x+=lowbit(x);
    }
}

int query(int l,int r)
{
    int ans=a[r]; // 不能用 rs[r] 否则直接就是 [1,r] 中的最大值了
    // 这里很关键,看图,如果想求 [1,16],但是之前假如到达了 C[8] 就结束了
    // 但本质上还不能结束,所以继续循环,下一个从 C[7] 开始,直到 l==r 为止
    while(l!=r)
    {
        for(r--; r-lowbit(r)>=l; r-=lowbit(r))
            ans=max(ans,rs[r]);
        // 注意:这里最后一个 r 还没有比较
        // 这里不能用 rs[r] 因为 rs[r] 的含义是 从 [1,r] 这个区间的最大值
        // 而这里到达最左边界时,就应该要用 a[r] 来进行最后一次的比较
        ans=max(ans,a[r]);
    }

    return ans;
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        mem(rs,0);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            update(i,a[i]);
        }

        char ch[5];
        int l,r;
        while(m--)
        {
            scanf("%s%d%d",ch,&l,&r);
            if(ch[0]=='Q') printf("%d\n",query(l,r));
            else update(l,r);
        }
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/Dream_Weave/article/details/81414081
今日推荐