A Simple Problem with Integers

A Simple Problem with Integers

这道题目只涉及区间修改以及区间查询,所以只要我们利用线段树或者树状数组进行优化,这道题就很容易解决了。

树状数组:因为树状数组本质上之能涉及单点更新,所以,当遇到区间更新的时候,可以尝试将其通项分解为 n 个维度,这样就可以通过 n+1 个树状数组对其进行维护。

// Created by CAD on 2020/2/9.
#include <cstdio>
#define ll long long
#define lowbit(i) (i&-i)
using namespace std;
const int maxn=1e5+5;
int a[maxn],n;
ll c0[maxn],c1[maxn];
void add(ll *c,int x,int k){
    while(x<=n)
        c[x]+=k,x+=lowbit(x);
}
ll getsum(ll *c,int x){
    ll sum=0;
    while(x>=1)
        sum+=c[x],x-=lowbit(x);
    return sum;
}
inline ll getallsum(int x){
    return getsum(c0,x)+getsum(c1,x)*x;
}
int main()
{
    int q;scanf("%d%d",&n,&q);
    for(int i=1;i<=n;++i)
        scanf("%d",&a[i]),add(c0,i,a[i]);
    while(q--){
        char bj[2];scanf("%s",bj);
        if(bj[0]=='Q'){
            int l,r;scanf("%d%d",&l,&r);
            ll ans=getallsum(r)-getallsum(l-1);
            printf("%lld\n",ans);
        }
        else{
            int l,r,c;scanf("%d%d%d",&l,&r,&c);
            add(c0,l,c*(1-l)),add(c1,l,c);
            add(c0,r+1,c*r),add(c1,r+1,-c);
        }
    }
    return 0;
}

线段树:

// Created by CAD on 2020/2/9.
#include <cstdio>
#define lson (p<<1)
#define rson (p<<1|1)
#define ll long long
using namespace std;

const int maxn=1e5+5;
int a[maxn],n;
ll d[maxn<<2],laz[maxn<<2];
void build(int s,int t,int p){
    if(s==t){
        d[p]=a[s];
        return ;
    }
    int mid=(s+t)>>1;
    build(s,mid,lson),build(mid+1,t,rson);
    d[p]=d[lson]+d[rson];
}
inline void pushdown(int s,int t,int p){
    int mid=(s+t)>>1;
    d[lson]+=(mid-s+1)*laz[p],d[rson]+=(t-mid)*laz[p];
    laz[lson]+=laz[p],laz[rson]+=laz[p];
    laz[p]=0;
}
void update(int l,int r,ll c,int s,int t,int p){
    if(l<=s&&t<=r){
        d[p]+=c*(t-s+1),laz[p]+=c;
        return ;
    }
    if(laz[p]) pushdown(s,t,p);
    int mid=(s+t)>>1;
    if(l<=mid) update(l,r,c,s,mid,lson);
    if(r>mid) update(l,r,c,mid+1,t,rson);
    d[p]=d[lson]+d[rson];
}
ll getsum(int l,int r,int s,int t,int p){
    if(l<=s&&t<=r) return d[p];
    int mid=(s+t)>>1;
    if(laz[p]) pushdown(s,t,p);
    ll sum=0;
    if(l<=mid) sum+=getsum(l,r,s,mid,lson);
    if(r>mid) sum+=getsum(l,r,mid+1,t,rson);
    return sum;
}

int main()
{
    int q;scanf("%d%d",&n,&q);
    for(int i=1;i<=n;++i)
        scanf("%lld",&a[i]);
    build(1,n,1);
    while(q--){
        char bj[3]; scanf("%s",bj);
        if(bj[0]=='Q'){
            int l,r;    scanf("%d%d",&l,&r);
            printf("%lld\n",getsum(l,r,1,n,1));
        }
        else{
            int l,r,c;  scanf("%d%d%d",&l,&r,&c);
            update(l,r,c,1,n,1);
        }
    }
    return 0;
}
posted @ 2020-02-09 14:28  caoanda  阅读(134)  评论(0编辑  收藏  举报