zoukankan      html  css  js  c++  java
  • HDU--1754 区间最值(树状数组做法)

    地址:http://acm.hdu.edu.cn/showproblem.php?pid=1754

         解析:先说update操作。c[]表示所管辖的区间范围里的最大值。

    void update(int id,int x)
    {
        while(id<=n)
        {
            c[id]=x;
            for(int i=1;i<lowbit(id);i+=lowbit(i))
            {
                c[id]=max(c[id],c[id-i]);
            }
            id+=lowbit(id);
        }
    }

        由于加入了一个新值,所以直接改变c[]是没有问题的。看这个for。举个例子:id=8,i=1,2,4。c[8]分别和c[4],c[6]c[7]进行了max更新,所以这个 id-i,是把所有id以内的区间进行了更新,覆盖了所有i<=id的数,很巧妙~。这个例子看这个图更是一目了然了:

        接下来是query操作:

    int query(int l,int r)
    {
        int md=0;
        while(l<=r)
        {
            md=max(md,a[r]);
            r--;
            for(;r-l>=lowbit(r);r-=lowbit(r))
            {
                md=max(md,c[r]);
            }
        }
        return md;
    }

        对于r来讲,它所管辖的有lowbit(r)个区间。所以对于[l,r]如果r-l>=lowbit(r),那么c[r]可以直接拿来用。而如果lowbit(r)超出了[l,r],那么就r--对L进行逼近。

        Ac代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+10;
    int c[maxn],a[maxn],n,m;
    int lowbit(int x)
    {
        return x&(-x);
    }
    void update(int id,int x)
    {
        while(id<=n)
        {
            c[id]=x;
            for(int i=1;i<lowbit(id);i+=lowbit(i))
            {
                c[id]=max(c[id],c[id-i]);
            }
            id+=lowbit(id);
        }
    }
    int query(int l,int r)
    {
        int md=0;
        while(l<=r)
        {
            md=max(md,a[r]);
            r--;
            for(;r-l>=lowbit(r);r-=lowbit(r))
            {
                md=max(md,c[r]);
            }
        }
        return md;
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            for(int i=1;i<=n;i++)
                c[i]=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                update(i,a[i]);
            }
            char ch[12];
            while(m--)
            {
                scanf("%s",ch);
                if(ch[0]=='Q')
                {
                    int l,r;
                    scanf("%d%d",&l,&r);
                    cout<<query(l,r)<<endl;
                }
                else
                {
                    int id,x;
                    scanf("%d%d",&id,&x);
                    a[id]=x;
                    update(id,x);
                }
            }
        }
    } 
  • 相关阅读:
    学习《Beginning iPhone 4 Development 》第6章关于View Switcher这个例子的问题
    Task、Thread、Process、Program
    Xcode Build版本号自增
    NSAutoreleasePool
    xml文件操作
    一些收集整理的JS
    网页常用小技巧
    40种网站设计常用技巧
    在虚拟主机中用ASP.NET1.1服务器端TIMER定时读取RSS信息到数据库
    删除服务器的文件夹后,session就丢失的问题
  • 原文地址:https://www.cnblogs.com/liyexin/p/12877821.html
Copyright © 2011-2022 走看看