zoukankan      html  css  js  c++  java
  • 1082 线段树练习 3 (线段树区间修改+区间求和)

    题目描述 Description

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


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


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

    输入描述 Input Description

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

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

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

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

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

    pascal选手请不要使用readln读入

    输出描述 Output Description

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

    样例输入 Sample Input

    3

    1

    2

    3

    2

    1 2 3 2

    2 2 3

    样例输出 Sample Output

    9

    数据范围及提示 Data Size & Hint

    数据范围

    1<=n<=200000

    1<=q<=200000

     
    思路:
    算是模板提吧,没什么难点,好久没写线段树了,写下熟悉下线段树区间操作,之前还有点不懂,后面自己独立写出来了感觉对这个的理解还是上升了。
     
    实现代码:
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    const int M = 2e5 + 10;
    ll lazy[M<<2],sum[M<<2];
    void pushup(int rt){
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    
    void pushdown(int rt,int m){
        if(lazy[rt]){
            lazy[rt<<1] += lazy[rt];
            lazy[rt<<1|1] += lazy[rt];
            sum[rt<<1] += lazy[rt]*(m-(m>>1));
            sum[rt<<1|1] += lazy[rt]*(m>>1);
            lazy[rt] = 0;
        }
    }
    
    void build(int l,int r,int rt){
        lazy[rt] = 0;
        if(l == r){
            cin>>sum[rt];
            return ;
        }
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    
    void update(int L,int R,int c,int l,int r,int rt){
        if(L <= l&&R >= r){
            lazy[rt] += c;
            sum[rt] += (r - l + 1)*c;
            return ;
        }
        pushdown(rt,r - l + 1);
        int m = (l + r) >> 1;
        if(L <= m) update(L,R,c,lson);
        if(R > m) update(L,R,c,rson);
        pushup(rt);
    }
    
    ll query(int L,int R,int l,int r,int rt){
        if(L <= l&&R >= r){
            return sum[rt];
        }
        pushdown(rt,r - l + 1);
        int m = (l + r) >> 1;
        ll ret = 0;
        if(L <= m)  ret += query(L,R,lson);
        if(R > m) ret += query(L,R,rson);
        return ret;
    }
    
    int main()
    {
        int n,q,x,l,r,c;
        cin>>n;
        build(1,n,1);
        cin>>q;
        while(q--){
            cin>>x;
            if(x == 1){
                cin>>l>>r>>c;
                update(l,r,c,1,n,1);
            }
            else{
                cin>>l>>r;
                cout<<query(l,r,1,n,1)<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    hdu 1455 N个短木棒 拼成长度相等的几根长木棒 (DFS)
    hdu 1181 以b开头m结尾的咒语 (DFS)
    hdu 1258 从n个数中找和为t的组合 (DFS)
    hdu 4707 仓鼠 记录深度 (BFS)
    LightOJ 1140 How Many Zeroes? (数位DP)
    HDU 3709 Balanced Number (数位DP)
    HDU 3652 B-number (数位DP)
    HDU 5900 QSC and Master (区间DP)
    HDU 5901 Count primes (模板题)
    CodeForces 712C Memory and De-Evolution (贪心+暴力)
  • 原文地址:https://www.cnblogs.com/kls123/p/8563162.html
Copyright © 2011-2022 走看看