一个简单的整数问题2

Posted 2462478392lee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个简单的整数问题2相关的知识,希望对你有一定的参考价值。

题意:给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:

   1、“C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d。

   2、“Q l r”,表示询问 数列中第 l~r 个数的和。

   对于每个询问,输出一个整数表示答案。

思路:用树状数组进行区间操作。用一个数组b[i]代表当操作为[l,r]同时d操作时则b[r+1]-d,b[l]+d。这样求的前后缀未变。树状数组维护b前缀,相当于只有b[l,r]变了,

然后再用个树状数组维护i*b[i]的前缀。所以求区间[l,r]的和等于(sum[r]+(r+1)*ask(b,r)-ask(c,r))-(sum[l-1]+(l-1+1)*ask(b,l-1)-ask(c,l-1))。如何维护详见代码。

#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;
const int N=2e5+10;
ll a[N],c[2][N],n,m,sum[N];
ll ask(int t,ll x)

    ll ans=0;
    for(;x;x-=lowbit(x))
        ans+=c[t][x];
    return ans;

void add(int t,ll x,ll y)

    for(;x<=n;x+=lowbit(x))
        c[t][x]+=y;

int main()

    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
    
        scanf("%lld",&a[i]);
        sum[i]=sum[i-1]+a[i];
    
    while(m--)
    
        ll l,r;
        ll t;
        ll ans;
        char s[2];
        scanf("%s",s);
        if(s[0]==Q)
        
            scanf("%lld%lld",&l,&r);
            ans=sum[r]+(r+1)*ask(0,r)-ask(1,r);
            ans-=sum[l-1]+l*ask(0,l-1)-ask(1,l-1);
            printf("%lld\n",ans);
        
        else
        
            scanf("%lld%lld%lld",&l,&r,&t);
            add(0,l,t);
            add(0,r+1,-t);
            add(1,l,l*t);
            add(1,r+1,-(r+1)*t);
        
    

 

以上是关于一个简单的整数问题2的主要内容,如果未能解决你的问题,请参考以下文章

如何利用一条简单语句判断一个整数是否为2的整数次幂

acwing 243. 一个简单的整数问题2 树状数组 线段树

243. 一个简单的整数问题2树状数组 区间查询 区间修改

C语言 这是一个很简单的题目,给定2个整数A和B,请输出A+B的和。

2750 鸡兔同笼(简单计算题)

LeetCode(周赛)2264:最大优质整数问题(简单)