zoukankan      html  css  js  c++  java
  • POJ 3468<线段树,区间add>

    题目连接

    //位运算
     k<<1   相当于  k*2
     k<<1|1 相当于 k*2+1
    /*
      修改区间内的值,并且维护区间和。
      详见代码
    */
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long  LL;
    const int maxn=100000+10;
    int a[maxn];
    struct tree
    {
        int l,r;
        LL sum;
        LL Inc;//延迟标记变量,表示[l,r]区间每个数增加Inc.
    
    }f[maxn*4];
    void bulid(int i,int l,int r)//maketree
    {
        f[i].l=l;
        f[i].r=r;
        f[i].Inc=0;
        if(l==r)
        {
            f[i].sum=a[l];//是a[l]不能是a[i],i代表的是节点的编号,在最后一行,l或者r代表的是第i个节点的次序。
            return ;
        }
        int mid=(l+r)>>1;
        bulid(i<<1, l, mid);
        bulid(i<<1|1, mid+1, r);
        f[i].sum=f[i<<1].sum+f[i<<1|1].sum;//维护和
    }
    void add(int i,int a,int b,LL c)
    {
        if(f[i].l==a&&f[i].r==b)//区间重合,直接标记Inc+=c;
        {
            f[i].Inc+=c;
            return ;
        }
      //区间不重合,更新当前区间的sum,pushdown
        f[i].sum+=c*(b-a+1);
        int mid=(f[i].l+f[i].r)>>1;
        if(b<=mid)
            add(i<<1, a, b, c);
        else if(a>=mid+1)
            add(i<<1|1, a, b, c);
        else
        {
            add(i<<1, a,mid, c);
            add(i<<1|1,mid+1,b,c);
        }
    }
    LL query(int i,int a,int b)//查询
    {
        if(f[i].l==a&&f[i].r==b)//区间重合
        {
            return f[i].sum+f[i].Inc*(b-a+1);
        }
    
        f[i].sum+=(f[i].r-f[i].l+1)*f[i].Inc;//相当于pushdown
        int mid=(f[i].l+f[i].r)>>1;
        add(i<<1, f[i].l, mid, f[i].Inc);
        add(i<<1|1,mid+1,f[i].r,f[i].Inc);
        f[i].Inc=0;
    
        if(b<=mid)
            return query(i<<1, a, b);
        else if(a>=mid+1) return query(i<<1|1, a, b);
        else return query(i<<1, a, mid)+query(i<<1|1, mid+1,b);
    }
    int main ()
    {
        int n,m;
        char s[5];
        int l,r;
        LL c;
        while(~scanf("%d%d",&n,&m))
        {
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            bulid(1, 1, n);
            for(int i=1;i<=m;i++)
            {
                scanf("%s",s);
                if(s[0]=='Q')
                {
                    scanf("%d%d",&l,&r);
                    printf("%lld
    ",query(1, l, r));
                }
                else
                {
                    scanf("%d%d%lld",&l,&r,&c);
                    add(1, l, r, c);
                }
            }
        }
        return 0;
    }
    想的太多,做的太少。
  • 相关阅读:
    Java安全之对称加密、非对称加密、数字签名
    Java 设计模式 之 中介者模式(Mediator)
    使用jquery获取radio的值
    java6枚举类型
    java http头信息
    怎样用java生成GUID与UUID
    struts2国际化
    JSON.stringify(),JSON.parse(),toJSON()方法使用
    阻塞队列之六:LinkedBlockingDeque
    jQuery给控件赋值....
  • 原文地址:https://www.cnblogs.com/pealicx/p/6115622.html
Copyright © 2011-2022 走看看