luogu P3372 【模板】线段树 1

luogu  P3372 【模板】线段树 1

线段树专门用来处理区间问题的,包括最大值,最小值,和

 

#include<cstdio>
#include<iostream>
using namespace std;
long long n,m;
long long s[1000010],tre[1000010],lan[1000010];
void build(long long i,long long l,long long r)
{
    if(l==r)
    {
        tre[i]=s[l];
        return;
    }
    long long mid=l+r>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    tre[i]=tre[i<<1]+tre[i<<1|1];
}
void jia(long long i,long long l,long long r,long long x,long long y,int k)
{//printf("*******l=%lld,r=%lld\n",l,r);
    if(x<=l&&r<=y)
    {
        lan[i]+=k;
        //for(long long o=1;o<=9;o++) printf("tre[%lld]=%lld,lan[%lld]=%lld\n",o,tre[o],o,lan[o]);
        return;
    }
    long long mid=(l+r)>>1;
    if(mid>=x) jia(i<<1,l,mid,x,y,k);
    if(mid+1<=y) jia(i<<1|1,mid+1,r,x,y,k);
    int a=max(l,x),b=min(r,y);
    tre[i]+=k*(b-a+1);
    //for(long long o=1;o<=9;o++) printf("tre[%lld]=%lld,lan[%lld]=%lld\n",o,tre[o],o,lan[o]);
}
long long he(long long i,long long l,long long r,long long x,long long y)
{
    //printf("*******l=%lld,r=%lld\n",l,r);
    if(l>=x&&r<=y)
    {
        //for(long long o=1;o<=9;o++) printf("tre[%lld]=%lld,lan[%lld]=%lld\n",o,tre[o],o,lan[o]);
        //printf("-------%lld\n",tre[i]+lan[i]*(l-r+1));
        return tre[i]+lan[i]*(r-l+1);
     } 
    long long mid=l+r>>1,ans=0;
    tre[i]+=lan[i]*(r-l+1);
    lan[i<<1]+=lan[i];
    lan[i<<1|1]+=lan[i];
    lan[i]=0;
    //for(long long o=1;o<=9;o++) printf("tre[%lld]=%lld,lan[%lld]=%lld\n",o,tre[o],o,lan[o]);
    if(mid>=x) ans+=he(i<<1,l,mid,x,y);
    if(mid+1<=y) ans+=he(i<<1|1,mid+1,r,x,y);
    return ans;
}
int main()
{
    long long k,x,y;
    scanf("%lld%lld",&n,&m);
    for(int j=1;j<=n;j++) scanf("%lld",&s[j]);
    build(1,1,n);
    for(int j=0;j<m;j++)
    {
        scanf("%lld",&k);
        if(k==1)
        {
            scanf("%lld%lld%lld",&x,&y,&k);
            jia(1,1,n,x,y,k);
            
        }
        else if(k==2)
        {
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",he(1,1,n,x,y));
            //for(long long o=1;o<=9;o++) printf("tre[%lld]=%lld,lan[%lld]=%lld\n",o,tre[o],o,lan[o]);
        }
    }
    return 0;
}

 

posted @ 2019-01-21 20:58  yyyr  阅读(133)  评论(0)    收藏  举报