线段树模板题

题目:codevs1080 1081 1082
分析:1080写的树状数组,1081 1082写的线段树,全是模板
这里写图片描述
这里写图片描述
这里写图片描述
代码:
1080

#include <cstdio>
#include <algorithm>
using namespace std;
const int Tmax=400010;
int n,p,v;
long long int sum[Tmax];
/*
int lowbit(int x)
{
    return x&-x;
}
*/
long long int query(int o,int l,int r)
{
    if(l>=p&&r<=v) return sum[o];
    int mid=l+(r-l)/2;
    long long int ans=0;
    if(p<=mid) ans=query(o*2,l,mid);
    if(mid<v) ans+=query(o*2+1,mid+1,r);
    return ans;
}
void updata(int o,int L,int R)
{
    int lc=o*2,rc=o*2+1,mid=L+(R-L)/2;
    if(L==R) sum[o]+=v;
    else
    {
        if(p<=mid) updata(lc,L,mid);
        else updata(rc,mid+1,R);
        sum[o]+=v;
    }
    return;
}
int main()
{
    int m,i,kind;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&v);
        p=i;
        updata(1,1,n);
    }
    scanf("%d",&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d %d %d",&kind,&p,&v);
        if(kind==1) updata(1,1,n);
        else printf("%lld\n",query(1,1,n));
    }
    return 0;
}

1081

#include <cstdio>
#include <algorithm>
using namespace std;
const int Tmax=800005; 
long long int sum[Tmax],ans,add[Tmax];
int ql,qr,v;
void query(int x,int l,int r,long long int addition)
{
    if(ql<=l&&r<=qr)
        ans+=sum[x]+addition*(r-l+1);
    else {
        int mid=l+(r-l)/2;
        if(mid>=ql) query(x*2,l,mid,addition+add[x]);
        if(mid<qr) query(x*2+1,mid+1,r,addition+add[x]);
    }
    return;
}
void maintain(int x,int l,int r)
{
    sum[x]=0;
    if(r>l) sum[x]=sum[x*2]+sum[x*2+1];
    sum[x]+=add[x]*(r-l+1);
    return;
}
void updata(int x,int l,int r)
{
    if(ql<=l&&r<=qr) add[x]+=v;
    else{
        int mid=l+(r-l)/2;
        if(mid>=ql) updata(x*2,l,mid);
        if(mid<qr) updata(x*2+1,mid+1,r);
    }
    maintain(x,l,r);
    return;
}
int main()
{
    int n,m,i,kind;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&v);
        ql=qr=i;
        updata(1,1,n);
    }
    scanf("%d",&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d",&kind);
        if(kind==1){
            scanf("%d %d %d",&ql,&qr,&v);
            updata(1,1,n);
        }
        else{
            ans=0;
            scanf("%d",&ql);
            qr=ql;
            query(1,1,n,0);
            printf("%lld\n",ans);
        }
    }
    return 0;
}

1082

#include <cstdio>
#include <algorithm>
using namespace std;
const int Tmax=800005; 
long long int sum[Tmax],ans,add[Tmax];
int ql,qr,v;
void query(int x,int l,int r,long long int addition)
{
    if(ql<=l&&r<=qr)
        ans+=sum[x]+addition*(r-l+1);
    else {
        int mid=l+(r-l)/2;
        if(mid>=ql) query(x*2,l,mid,addition+add[x]);
        if(mid<qr) query(x*2+1,mid+1,r,addition+add[x]);
    }
    return;
}
void maintain(int x,int l,int r)
{
    sum[x]=0;
    if(r>l) sum[x]=sum[x*2]+sum[x*2+1];
    sum[x]+=add[x]*(r-l+1);
    return;
}
void updata(int x,int l,int r)
{
    if(ql<=l&&r<=qr) add[x]+=v;
    else{
        int mid=l+(r-l)/2;
        if(mid>=ql) updata(x*2,l,mid);
        if(mid<qr) updata(x*2+1,mid+1,r);
    }
    maintain(x,l,r);
    return;
}
int main()
{
    int n,m,i,kind;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&v);
        ql=qr=i;
        updata(1,1,n);
    }
    scanf("%d",&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d",&kind);
        if(kind==1){
            scanf("%d %d %d",&ql,&qr,&v);
            updata(1,1,n);
        }
        else{
            ans=0;
            scanf("%d %d",&ql,&qr);
            query(1,1,n,0);
            printf("%lld\n",ans);
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值