menu 雨落亭
search
poj 3468 (线段树)
雨落
雨落
Time:
share




成段更新

这题数据很大,注意要__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\n",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

*/

评论

   textsms
   account_circle
昵称不能为空
   email
邮箱格式错误
   language





message 没有评论惹=_=

arrow_back 上一篇
arrow_back 上一篇
poj 2528 (线段树)
下一篇 arrow_forward
没有了
下一篇 arrow_forward
没有了