线段树 POJ 3468

  这周学习了一下线段树,偶遇POJ 3468,这道题是线段树区间更新,题意大概是有一段的长为n的数组,经过若干次对其中某一段的数进行加减,询问某一段的和。这题还是比较明显的线段树,如果细分到对每一个节点进行操作的话,复杂度为O(m^logn),容易超时,所以采取延迟标记的做法,直接对某一段进行操作,而暂不对其子树进行操作,话不多说,直接上代码吧

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include <iostream>  
#include<algorithm>
#include<cmath>
using  namespace  std; 

struct node 
{
    int x,y,sign;
    long long sum,ad; 
} ;

node tree[400010];
long long v[100010];

long long maketree(int x,int y,int z)
{
    tree[z].x=x;
    tree[z].y=y;
    if(x>=y) return tree[z].sum=v[x];
    else return tree[z].sum=maketree(x,(x+y)/2,2*z)+maketree((x+y)/2+1,y,2*z+1);
}

void down(int q)
{
    tree[q].sign=0;
    tree[2*q].sign=tree[2*q+1].sign=1;
    tree[2*q].ad+=tree[q].ad;
    tree[2*q+1].ad+=tree[q].ad;
    tree[2*q].sum+=tree[q].ad*(tree[2*q].y-tree[2*q].x+1);
    tree[2*q+1].sum+=tree[q].ad*(tree[2*q+1].y-tree[2*q+1].x+1);
    tree[q].ad=0;
}

void add(int x,int y,int z,int q)
{
    if(x<=tree[q].x&&y>=tree[q].y) 
    {
        tree[q].sign=1;
        tree[q].sum+=z*(tree[q].y-tree[q].x+1);
        tree[q].ad+=z;
        return ;
    }
    if(tree[q].sign==1) down(q);
    if(x<=(tree[q].x+tree[q].y)/2) add(x,y,z,2*q);
    if(y>=(tree[q].x+tree[q].y)/2+1) add(x,y,z,2*q+1);
    tree[q].sum=tree[2*q].sum+tree[2*q+1].sum;
    return; 
}

long long find(int x,int y,int q)
{
    if(x>tree[q].y||y<tree[q].x) return 0;
    if(x<=tree[q].x&&y>=tree[q].y) return tree[q].sum;
    if(tree[q].sign==1) down(q);
    return find(x,y,2*q)+find(x,y,2*q+1);
}

int main()
{
    int n,q,x,y,z,i,k;
    long long sum;
    char ch;
    scanf("%d%d",&n,&q);
    memset(tree,0,sizeof(tree));
    for(k=1;k<=n;k++)
    {
        scanf("%lld",&v[k]);
    }
    maketree(1,n,1);
    for(i=1;i<=q;i++)
    {
        scanf("%*c%c",&ch);
        if(ch=='C')
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z,1);
        }
        else if(ch=='Q')
        {
            scanf("%d%d",&x,&y);
            sum=find(x,y,1);
            printf("%lld\n",sum);
        }
    }
    return 0;
}

 

posted on 2015-05-30 19:44  BBLC  阅读(217)  评论(2编辑  收藏  举报