线段树练习3

区间修改,区间查询!

 

 

#include<iostream>
#include<cstdio>

using namespace std;

int n,m,type;
struct node{
    int l,r;long long dis,flag;
}tre[800001];

long long init()
{
    long long x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

void build(int now,int l,int r)
{
    tre[now].l=l;tre[now].r=r;
    if(l==r)
    {
        tre[now].dis=init();
        return;
    }
    int mid=(l+r)>>1;
    build(now<<1,l,mid);
    build(now<<1|1,mid+1,r);
    tre[now].dis=tre[now<<1].dis+tre[now<<1|1].dis;
}

void tree_flag(int now)
{    
    if(tre[now].r==tre[now].l) return;
    tre[now<<1].flag+=tre[now].flag;
    tre[now<<1|1].flag+=tre[now].flag;
    tre[now<<1].dis+=tre[now].flag*(tre[now<<1].r-tre[now<<1].l+1);
    tre[now<<1|1].dis+=tre[now].flag*(tre[now<<1|1].r-tre[now<<1|1].l+1);
    tre[now].flag=0;
}

void Change(int now,int l,int r,int k)
{
    if(tre[now].l==l&&tre[now].r==r)
    {
        tre[now].dis+=(r-l+1)*k;
        tre[now].flag+=k;
        return;
    }
    if(tre[now].flag) tree_flag(now);
    int mid=(tre[now].l+tre[now].r)>>1;
    if(l>mid) Change(now<<1|1,l,r,k);
    else if(r<=mid) Change(now<<1,l,r,k);
    else
    {
        Change(now<<1,l,mid,k);
        Change(now<<1|1,mid+1,r,k);
    }
    tre[now].dis=tre[now<<1].dis+tre[now<<1|1].dis;
}

long long int Query(int now,int l,int r)
{
    if(tre[now].l==l&&tre[now].r==r)
    {
        return tre[now].dis;
    }
    if(tre[now].flag)tree_flag(now);
    tre[now].dis=tre[now<<1].dis+tre[now<<1|1].dis;
    int mid=(tre[now].l+tre[now].r)>>1;
    if(l>mid)return Query(now<<1|1,l,r);
    else if(r<=mid)return Query(now<<1,l,r);
    else
    {
        return Query(now<<1,l,mid)+Query(now<<1|1,mid+1,r);
    }
}

int main()
{
    n=init();
    build(1,1,(int)n);
    m=init();
    long long int l,r,x;
    for(int i=1;i<=m;i++)
    {
        type=init();
        if(type==1)
        {
            l=init(),r=init(),x=init();
            Change(1,(int)l,(int)r,(int)x);
        }
        else
        {
            l=init(),r=init();
            printf("%lld\n",Query(1,(int)l,(int)r));
        }
    }
    return 0;
}
心若向阳,无言悲伤

 

posted @ 2017-01-18 17:02  安月冷  阅读(179)  评论(0编辑  收藏  举报