zoukankan      html  css  js  c++  java
  • 【codevs】1082 线段树练习 3 <区间修改+区间和>

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

    Description

    给你N个数,有两种操作:


    1:给区间[a,b]的所有数增加X


    2:询问区间[a,b]的数的和。

    Input

    第一行一个正整数n,接下来n行n个整数,

    再接下来一个正整数Q,每行表示操作的个数,

    如果第一个数是1,后接3个正整数,

    表示在区间[a,b]内每个数增加X,如果是2,

    表示操作2询问区间[a,b]的和是多少。

    输出描述 Output Description

    对于每个询问输出一行一个答案

    Sample Input

    3

    1

    2

    3

    2

    1 2 3 2

    2 2 3

    Sample ouput

    9

    数据范围及提示 Data Size & Hint

    数据范围

    1<=n<=200000

    1<=q<=200000

    代码

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <queue>
    #include <typeinfo>
    #include <map>
    #include <stack>
    typedef long long ll;
    #define inf 0x7fffffff
    using namespace std;
    inline ll read()
    {
        ll x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    //**************************************************************************************
    struct ss
    {
        int l,r;
        ll sum;
        int tag;
    }tr[4*200005];
    int n;
    int a[200005];
    void build(int k,int l,int r)
    {
        tr[k].l=l;
        tr[k].r=r;
        if(l==r) {tr[k].sum=a[l];return;}
        int mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
    }
    void pushdown(int k)
    {
        int x=tr[k].r-tr[k].l+1;
        tr[k<<1].tag+=tr[k].tag;
        tr[k<<1|1].tag+=tr[k].tag;
        tr[k<<1].sum+=(x-(x>>1))*tr[k].tag;
        tr[k<<1|1].sum+=(x>>1)*tr[k].tag;
        tr[k].tag=0;
    }
    void update(int k,int a,int b,int x)
    {
        if(a==tr[k].l&&b==tr[k].r)
        {
            tr[k].tag+=x;
            tr[k].sum+=(b-a+1)*x;
            return ;
        }
        if(tr[k].tag)pushdown(k);
        int mid=(tr[k].l+tr[k].r)>>1;
        if(b<=mid)update(k<<1,a,b,x);
        else if(a>mid)update(k<<1|1,a,b,x);
        else {
           update(k<<1,a,mid,x);
       update(k<<1|1,mid+1,b,x);
        }
        tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
    }
    ll ask(int k,int a,int b)
    {
        if(a==tr[k].l&&b==tr[k].r){return tr[k].sum;}
        if(tr[k].tag) pushdown(k);
        int mid=(tr[k].l+tr[k].r)>>1;
        if(b<=mid)return ask(k<<1,a,b);
        else if(a>mid) return ask(k<<1|1,a,b);
        else {
            return (ask(k<<1,a,mid)+ask(k<<1|1,mid+1,b));
        }
    }
    int main()
    {
    
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        build(1,1,n);
        int q;
       scanf("%d",&q);
        for(int i=1;i<=q;i++)
        {
            int x,aa,b,mm;
            scanf("%d",&mm);
            if(mm==1)
            {
                scanf("%d%d%d",&aa,&b,&x);
                update(1,aa,b,x);
            }
            else
            {
                scanf("%d%d",&aa,&b);
                printf("%lld
    ",ask(1,aa,b));
            }
        }
        return 0;
    }
  • 相关阅读:
    中风后遗症
    慢性湿疹半年
    女子脚背痒肿案
    肾盂肾炎病案
    鼻衄二则
    糖尿病病案
    慢性肠炎2例
    子宫肌瘤病案2例
    眩晕病案
    前列腺炎病案3例
  • 原文地址:https://www.cnblogs.com/zxhl/p/4684082.html
Copyright © 2011-2022 走看看