• poj 3468


    成段更新

    这题数据很大,注意要__int64 。

    其他差不多,

    /*
    poj 3468 
    注意标签的作用,注意是+=,才能传递正确的值下去,一定要注意到这定,标签的值 
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    #define MAX 150000
    using namespace std;
    typedef struct node
    {
     int s,e;
     __int64 mark;
     __int64 sum;
     node (int a=0,int b=0,__int64 c=0,__int64 d=0):s(a),e(b),mark(c),sum(d){};
    }node;
    
    node tree[4*MAX];
    __int64 num[MAX];  
    int flag=0;
    /*这里真是坑,注意用__int64才行,什么LONG LONG 都WR __int64 就AC*/ 
    
    void build (int T,int s,int e)
    {
        if (s==e)
         tree[T] = node(s,e,0,num[flag++]);
        else
        {
          int mid = (s+e)>>1;
          build(T<<1,s,mid);
          build (T<<1|1,mid +1 ,e);
          tree[T]=node (s,e,0,tree[T<<1].sum+tree[T<<1|1].sum);
        }
    } 
    
    void change_down(int T)
    {
        if (tree[T].mark)
        { 
         tree[T<<1].mark +=tree[T].mark; tree[T<<1|1].mark += tree[T].mark; //标签一定是+=,才能把最终到底是多少 
         tree[T<<1].sum += (tree[T<<1].e-tree[T<<1].s+1)*tree[T].mark; //的和传递下去 
         tree[T<<1|1].sum += (tree[T<<1|1].e-tree[T<<1|1].s+1)*tree[T].mark;
         tree[T].mark = 0;//记得消除标记 } 
        } 
    }
    
    void update(int T,int s,int e,int p)
    {
       if (s<= tree[T].s&& e>=tree[T].e)
        {
            tree[T].mark += p;//这里一定要用+= 因为,不断操作,比如+3 +4 那么向下传递时 
            tree[T].sum += (tree[T].e-tree[T].s+1)*p;  //一定是+7,而不是用赋值,这样就变成了 
        }                                              //传递4了, 
       else
       {   
            change_down(T);//当前节点是否标记过,是的话,标签下移 
              int mid = (tree[T].s+tree[T].e)>>1;
              if (s<=mid) update(T<<1,s,e,p);
              if (e>mid)  update (T<<1|1,s,e,p);
              tree[T].sum = tree[T<<1].sum+tree[T<<1|1].sum;
       }
    } 
    
    __int64 Query(int T,int s,int e)
    {
        if (s<=tree[T].s && e>=tree[T].e)
        {
            return tree[T].sum;
        }
        else  //该区间未包含需要向下,或者未标记也需要向下, 
        {
            change_down(T);
            int mid  = (tree[T].s + tree[T].e)>>1;
            __int64 s1 = 0;
            if (s<=mid)  s1 += Query(T<<1,s,e);
            if (e>mid)   s1 += Query(T<<1|1,s,e);
            return s1;
        }
    }
    
    int main ()
    {
    
        int n,q;
        scanf ("%d%d",&n,&q);
        for (int i=0;i<n;++i)
         scanf ("%I64d",&num[i]);
         flag = 0;
         build (1,1,n);
         char c[4];int a1,b1,c1;
         for (int i=0;i<q;++i)
          { 
               scanf ("%s",&c);//用单个字符会出毛病,所以用串 
              if (c[0]=='Q')
               {
                 scanf ("%d %d",&a1,&b1);
                 printf ("%I64d
    ",Query(1,a1,b1));
               }
               else
               {
                   scanf ("%d %d %d",&a1,&b1,&c1);
                   update(1,a1,b1,c1);
               }
          }
        return 0;
    }
    /*
    10 5
    1 2 3 4 5 6 7 8 9 10
    Q 4 4
    Q 1 10
    Q 2 4
    C 3 6 3
    Q 2 4
    
    */
  • 相关阅读:
    vue之过滤器的用法
    数组方法
    vue指令之 v-fo循环和 v-show 以及key值的用法
    清除浮动的几种方式
    cookie和session的区别
    layui添加新增弹出框
    layui如何实现图片上传功能
    css中设置背景图片平铺整个页面
    在vue中使用样式的方法
    windows最小最大化当前窗口和关闭当前窗口
  • 原文地址:https://www.cnblogs.com/yuluoluo/p/8047807.html
Copyright © 2020-2023  润新知