• POJ_3468_Interval Tree 更新区间经典


    --
    /*
        POJ_3468_Interval Tree 更新区间  与 h1698 类似,但是你要清楚他们的区别 -- 为负,随时查询任意一个区间,上下面 
        Author  : a_clay    Created : 2012-02-04
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #define get_mid(x) ((x) >> 1)
    
    using namespace std;
    
    const int N = 100005;
    struct node {
        int a, b;
        long long sum;
        long long kind;
    }t[3*N];
    
    int n, m;
    int r[N];
    long long SUM;
    void make_tree(int x, int y, int num) {
        t[num].a = x;
        t[num].b = y;
        t[num].kind = 0;
        if (x == y) {
            t[num].sum = r[y];
        }
        else {
            make_tree(x, get_mid(x+y), 2*num);
            make_tree(get_mid(x+y)+1, y, 2*num+1);
            t[num].sum = t[2*num].sum + t[2*num+1].sum;
        }
    }
    void add(int x, int y, int z, int num) {
        if (x <= t[num].a && t[num].b <= y) { // 找终止节点 
            t[num].sum += (t[num].b - t[num].a + 1) * z;
            t[num].kind += z;
        }
        else {
            if (t[num].kind != 0) {
                t[2*num].kind += t[num].kind;
                t[2*num+1].kind += t[num].kind;
                t[2*num].sum += (t[2*num].b - t[2*num].a + 1) * t[num].kind;
                t[2*num+1].sum += (t[2*num+1].b - t[2*num+1].a + 1) * t[num].kind;
                t[num].kind = 0; // 必须 
            }
            
            int mid = get_mid(t[num].a + t[num].b);
            if (x <= mid) {
                add(x, y, z, 2*num);
            }
            if (y > mid) {
                add(x, y, z, 2*num+1);
            }
            t[num].sum = t[2*num].sum + t[2*num+1].sum;
        }
    }
    void query(int x, int y, int num) {
        if (x <= t[num].a && t[num].b <= y) {
            SUM += t[num].sum;
        }
        else {
            if (t[num].kind != 0) {
                t[2*num].kind += t[num].kind;
                t[2*num+1].kind += t[num].kind;
                t[2*num].sum += (t[2*num].b - t[2*num].a + 1) * t[num].kind;
                t[2*num+1].sum += (t[2*num+1].b - t[2*num+1].a + 1) * t[num].kind;
                t[num].kind = 0; // 优化 
            }
            int mid = get_mid(t[num].a + t[num].b);
            if (x <= mid) {
                query(x, y, 2*num);
            }
            if (y > mid) {
                query(x, y, 2*num+1);
            }
        }
    }
    int main() {
        int i;
        memset(t, 0, sizeof(t));
        scanf("%d%d", &n, &m);
        for (i = 1; i <= n; i++) {
            scanf("%d", &r[i]);
        }
        make_tree(1, n, 1);
        while (m--) {
            int a, b, c;
            char str[3];
            scanf("%s", str);
            if (str[0] == 'C') {
                scanf("%d%d%d", &a, &b, &c);
                add(a, b, c, 1);
            }
            else {
                scanf("%d%d", &a, &b);
                SUM = 0;
                query(a, b, 1);
                cout << SUM << endl;
            }
        }
        system("pause");
        return 0;
    }
            
    

  • 相关阅读:
    MyBatis的Mapper接口以及Example的实例函数及详解
    数据存储
    广播
    java线程复习3(线程的中断)
    java线程复习2(获取和设置线程信息)
    java线程复习1(线程创建)
    最好的启动方式
    工厂模式
    欧几里得算法
    组合数打表
  • 原文地址:https://www.cnblogs.com/robbychan/p/3786772.html
Copyright © 2020-2023  润新知