CODEVS 1082 (区间查询+区间求和)

Posted lllaih

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CODEVS 1082 (区间查询+区间求和)相关的知识,希望对你有一定的参考价值。

题目链接:http://codevs.cn/problem/1082/

注意更新区间求和时,应该加上的是这一段区间包含的元素的个数乘以更新的值

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <cstring>
#include <map>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn = 4000005;
const ll INF = 0x3f3f3f3f3f;
int dir[8][2]= 0,1,1,0,0,-1,-1,0,1,-1,-1,-1,1,1,-1,1;
int dir2[4][2]= 0,1,0,-1,1,0,-1,0;
bool flag;
ll a[maxn],sum[maxn],n,ans,num[maxn];
struct node
    ll l;
    ll r;
b[maxn];
void pushup(ll k)

    sum[k] = sum[k*2] + sum[k*2+1];

void build(ll k,ll l,ll r)//递归建树

    if(l == r)
    
        b[k].l = l,b[k].r = r;
        sum[k] = a[l];
        return ;
    
    else
    
        ll mid = (l+r) / 2;
        b[k].l = l,b[k].r=r;
        build(k<<1,l,mid);
        build(k*2+1,mid+1,r);
        pushup(k);
    

void pushdown(ll k)

    if(num[k])
        num[k<<1] += num[k];
        num[k*2+1] += num[k];
        sum[k<<1] += (b[k*2].r-b[k*2].l+1)*num[k];
        sum[k*2+1] += (b[k*2+1].r-b[k*2+1].l+1)*num[k];
        num[k] = 0;
    

void update(ll l,ll r,ll L,ll R,ll k,ll v)//单点更新

    if(L >= l && R <= r)
    
        sum[k] += (b[k].r-b[k].l+1)*v;
        num[k] += v;
        return ;
    
    else
    
        pushdown(k);
        ll mid = (L + R) / 2;
        if(l <= mid) update(l,r,L,mid,k*2,v);
        if(mid < r) update(l,r,mid+1,R,k*2+1,v);
        pushup(k);
    

void Search(ll l,ll r,ll L,ll R,ll k)//区间查询

    if(L >= l&& R <= r)
    
        ans += sum[k];
        return;
    
    pushdown(k);
    ll mid = (L + R) / 2;
    if(mid >= l)  Search(l,r,L,mid,k*2);
    if(mid < r)  Search(l,r,mid+1,R,k*2+1);

int main()

    ll m;
    cin >> n;
    for(ll i = 1; i <= n; i++)
    
        cin >> a[i];
    
    mem(sum);
    build(1,1,n);//建树
    ll z,x,c,s;
    cin >> m;
    for(ll i = 1; i <= m; i++)
    
        cin >> z;
        if(z == 1)
            
                cin >> x >> c >> s;
                update(x,c,1,n,1,s);
            
        else
        
           cin >> x >> c;
           ans = 0;
           Search(x,c,1,n,1);
           cout << ans << endl;
        
    
    return 0;

 

以上是关于CODEVS 1082 (区间查询+区间求和)的主要内容,如果未能解决你的问题,请参考以下文章

codevs1082线段树练习 3

codevs1082

线段树练习3 codevs1082

一维数状数组区间修改,查询

codevs 1082 线段树联系3

codevs 1082 线段树练习3