poj 3468 A Simple Problem with Integers(线段树 [区间更新])

来源:互联网 发布:vb cstr函数 编辑:程序博客网 时间:2024/06/06 09:03

A Simple Problem with Integers
Time Limit: 5000MS Memory Limit: 131072KTotal Submissions: 78109 Accepted: 24051Case Time Limit: 2000MS点击打开链接

Description

You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4

Sample Output

455915

Hint

The sums may exceed the range of 32-bit integers.

题意:

         给出了一个序列,你需要处理如下两种询问。

          "C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。


           "Q a b" 询问[a, b]区间中所有值的和。

            第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.

           第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。

             接下来Q行询问,格式如题目描述。

思路:

        一看本题就是区间更新,与单点更新有所不同

       有关update函数我们需要pushdown函数来维护整个区间的值,不是和单点更新相同,所以如下。

注意:

    本题大坑:

    我做的时候数组开小了,不仅sum要4倍的,而且add,num,均要四倍,一下午把我给郁闷了

维护函数:      

void pushup(int v){   sum[v]=sum[v<<1]+sum[v<<1|1];}void pushdown(int l,int r,int v){if(add[v]!=0) {           add[v<<1]+= add[v]; //左子树需要加add[v<<1|1]+=add[v]; //右子树需要加        sum[v<<1]+= (mid+1-l)*add[v];//左子树求和         sum[v<<1|1]+=(r-mid)*add[v]; //右子树求和         add[v]=0;//这儿不能少         }  }void update(int l,int r,int v,int lpos,int rpos,int x){if(l>rpos||r<lpos)return ;if(l>=lpos&&r<=rpos){  sum[v]+=(LL)(r-(l-1))*x;  add[v]+=x;  return ;}pushdown(l,r,v);if(l<=mid) update(lson,lpos,rpos,x);if(r>mid)update(rson,lpos,rpos,x);pushup(v);}

本人AC代码:

#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>using namespace std;#define  MAX 100000typedef long long int LL;#define mid (l+r>>1)#define lson l,mid,v<<1#define rson mid+1,r,v<<1|1LL sum[4*MAX+20],num[4*MAX+5],add[4*MAX+5];//注意范围void init(){memset(sum,0,sizeof(sum));memset(add,0,sizeof(add));memset(num,0,sizeof(num));}void pushup(int v){   sum[v]=sum[v<<1]+sum[v<<1|1];}void pushdown(int l,int r,int v){if(add[v]!=0) {           add[v<<1]+= add[v]; add[v<<1|1]+=add[v];          sum[v<<1]+= (mid+1-l)*add[v];         sum[v<<1|1]+=(r-mid)*add[v];          add[v]=0;          }  }void build(int l,int r,int v){  add[v]=0;  if(l==r)  {  sum[v]=num[l];  return ;  }  build(lson);  build(rson);    pushup(v);}void update(int l,int r,int v,int lpos,int rpos,int x){if(l>rpos||r<lpos)//这儿剪枝不能少return ;if(l>=lpos&&r<=rpos){  sum[v]+=(LL)(r-(l-1))*x;//注意(LL)和(r-(l-1))  add[v]+=x;  return ;}pushdown(l,r,v);if(l<=mid) update(lson,lpos,rpos,x);if(r>mid)update(rson,lpos,rpos,x);pushup(v);}LL query(int l,int r,int v,int lpos,int rpos){if(l>rpos||r<lpos)//同上return 0;if(l>=lpos&&r<=rpos)    return sum[v];    pushdown(l,r,v);    return query(lson,lpos,rpos)+query(rson,lpos,rpos);    }int main(){  int n,m;  while(~scanf("%d%d",&n,&m))   {init();for(int i=1;i<=n;i++)   scanf("%lld",&num[i]); build(1,n,1);while(m--){  char opr;  getchar();//他少了会很难看的  scanf("%c",&opr);   int a,b,c;          if(opr=='Q')  {   scanf("%d%d",&a,&b);   LL ans=query(1,n,1,a,b);   printf("%lld\n",ans); } else { scanf("%d%d%d",&a,&b,&c); update(1,n,1,a,b,c);        }       }   }  return 0;}


队友AC代码:

#include <stdio.h>#define N 100100#define LL long long#define lson l,m,v<<1#define rson m+1,r,v<<1|1LL add[4*N];LL sum[4*N];void PushUP(int v){    sum[v]=sum[v<<1]+sum[v<<1|1];}void PushDown(int v,int m){    if(add[v])    {        add[v<<1]+=add[v];        add[v<<1|1]+=add[v];        sum[v<<1]+=(m-(m>>1))*add[v];        sum[v<<1|1]+=(m>>1)*add[v];        add[v]=0;    }}void Build(int l,int r,int v){    add[v]=0;    if(l==r)    {        scanf("%lld",&sum[v]);        return;    }    int m=(l+r)>>1;    Build(lson);    Build(rson);    PushUP(v);}void Update(int L,int R,int c,int l,int r,int v){    if(L<=l&&R>=r)    {        add[v]+=(LL)c;        sum[v]+=(LL)c*(r-l+1);        return;    }    PushDown(v,r-l+1);    int m=(l+r)>>1;    if(L<=m)        Update(L,R,c,lson);    if(R>m)        Update(L,R,c,rson);    PushUP(v);}LL Query(int L,int R,int l,int r,int v){    if(L<=l&&R>=r)        return sum[v];    PushDown(v,r-l+1);    int m=(l+r)>>1;    LL ret=0;    if(L<=m)   ret+=Query(L,R,lson);    if(R>m)    ret+=Query(L,R,rson);    return ret;}int main(){    int m,n;    scanf("%d%d",&n,&m);    Build(1,n,1);    for(int i=0;i<m;i++)    {        char s[2];        int a,b,c;        scanf("%s",s);        if(s[0]=='Q')        {            scanf("%d %d",&a,&b);            printf("%lld\n",Query(a,b,1,n,1));        }        else        {            scanf("%d %d %d",&a,&b,&c);            Update(a,b,c,1,n,1);        }    }    return 0;}




0 0
原创粉丝点击