zoukankan      html  css  js  c++  java
  • poj 3468 , 线段树

    A Simple Problem with Integers
    Time Limit: 5000MS   Memory Limit: 131072K
    Total Submissions: 50205   Accepted: 14911
    Case Time Limit: 2000MS

    Description

    You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

    Input

    The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
    The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
    Each of the next Q lines represents an operation.
    "C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
    "Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

    Output

    You need to answer all Q commands in order. One answer in a line.

    Sample Input

    10 5
    1 2 3 4 5 6 7 8 9 10
    Q 4 4
    Q 1 10
    Q 2 4
    C 3 6 3
    Q 2 4
    

    Sample Output

    4
    55
    9
    15

    Hint

    The sums may exceed the range of 32-bit integers.

    Source

     
    线段树,区间和,延迟标记
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<set>
    #include<queue>
    #include<string>
    #include<cmath>
    #include<fstream>
    #include<iomanip>
    
    using namespace std;
    
    #define LL long long
    #define lson rt<<1, l, m
    #define rson rt<<1|1, m, r
    #define MAXN 111111
    
    int n, q;
    LL sum[MAXN<<2], todo[MAXN<<2];
    
    void push_up(int rt){ sum[rt] = sum[rt<<1] + sum[rt<<1|1]; }
    
    void push_down(int rt, int l, int r){
        if(!todo[rt]) return;
        todo[rt<<1] += todo[rt];    todo[rt<<1|1] += todo[rt];
        int m = l + r >> 1;
        sum[rt<<1] += (m - l) * todo[rt];
        sum[rt<<1|1] += (r - m) * todo[rt];
        todo[rt] = 0;
    }
    
    void build(int rt, int l, int r){
        todo[rt] = 0;
        if(l+1 == r){
            scanf(" %lld", sum+rt);  return;
        }
        int m = l + r >> 1;
        build(lson);
        build(rson);
        push_up(rt);
    }
    
    void update(int rt, int l, int r, int cl, int cr, int tc){
        if(cl<=l && cr>=r){
            todo[rt] += tc;  sum[rt] += (r - l) * tc;
            return;
        }
        int m = l + r >> 1;
        push_down(rt, l, r);
        if(cl < m) update(lson, cl, cr, tc);
        if(cr > m) update(rson, cl, cr, tc);
        push_up(rt);
    }
    
    LL query(int rt, int l, int r, int cl, int cr){
        if(cl<=l && cr>=r) return sum[rt];
        int m = l + r >> 1;
        LL ret = 0;
        push_down(rt, l, r);
        if(cl < m) ret += query(lson, cl, cr);
        if(cr > m) ret += query(rson, cl, cr);
        return ret;
    }
    
    int main(){
    //    freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin);
        while(scanf(" %d %d", &n, &q)==2){
            build(1, 1, 1+n);
            while(q--){
                int a, b, c;    char ch;
                scanf(" %c %d %d", &ch, &a, &b);    b++;
                if(ch == 'C'){
                    scanf(" %d", &c);
                    update(1, 1, 1+n, a, b, c);
                }
                else printf("%lld
    ", query(1, 1, 1+n, a, b));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Android实现通过浏览器点击链接打开本地应用(APP)并拿到浏览器传递的数据(转)
    保存图片文件到本地
    android ScrollView中嵌套GridView,ListView只显示一行的解决办法
    蒙版提示页(添加新功能后的一种提示)
    C和指针 第三章--数据
    *(ptr++) += 123
    优先级队列-堆
    单链表相关(一)
    字符间的距离-动态规划
    和最大的连续子数组
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3391665.html
Copyright © 2011-2022 走看看