• poj 3468 A Simple Problem with Integers 线段树 题解《挑战程序设计竞赛》


    地址 http://poj.org/problem?id=3468 

    线段树模板 

    要背下此模板

    线段树
      1 #include <iostream>
      2 #include <vector>
      3 #include <math.h>
      4 #include <algorithm>
      5 
      6 
      7 using namespace std;
      8 
      9 /*
     10 Sample Input
     11 10 5
     12 1 2 3 4 5 6 7 8 9 10
     13 Q 4 4
     14 Q 1 10
     15 Q 2 4
     16 C 3 6 3
     17 Q 2 4
     18 Sample Output
     19 4
     20 55
     21 9
     22 15
     23 */
     24 typedef long long ll;
     25 
     26 const int  DAT_SIZE = (1 << 18) - 1;
     27 
     28 const int MAX_N = 100000010;
     29 
     30 //输入
     31 int N, Q;
     32 int A[MAX_N];
     33 char T[MAX_N];
     34 int L[MAX_N], R[MAX_N], X[MAX_N];
     35 
     36 //线段树
     37 ll dat_a[DAT_SIZE], dat_b[DAT_SIZE];
     38 
     39 //对区间[a,b]同时加x
     40 //k是节点的编号 对应的空间是[l,r)
     41 void add(int a, int b, int x, int k, int l, int r)
     42 {
     43     if (a <= l && r <= b) {
     44         dat_a[k] += x;
     45     }
     46     else if (l < b && a < r) {
     47         dat_b[k] += (min(b,r)-max(a,l))* x;
     48         add(a, b, x, k * 2 + 1, l, (l + r) / 2);
     49         add(a, b, x, k * 2 + 2, (l + r) / 2, r);
     50     }
     51 }
     52 
     53 //计算[a,b)的和
     54 //k是节点的编号 对应的区间是[l,r)
     55 ll sum(int a, int b, int k, int l, int r)
     56 {
     57     if (b <= l || r <= a) {
     58         return 0;
     59     }
     60     else if(a <= l && r <= b){
     61         return dat_a[k] * (r - l) + dat_b[k];
     62     }
     63     else {
     64         ll res = (min(b,r)-max(a,l)) * dat_a[k];
     65         res += sum(a, b, k * 2 + 1, l, (l + r) / 2);
     66         res += sum(a, b, k * 2 + 2, (l + r) / 2, r);
     67         return res;
     68     }
     69 }
     70 
     71 void solve()
     72 {
     73     for (int i = 0; i < N; i++) {
     74         add(i, i + 1, A[i], 0, 0, N);
     75     }
     76     for (int i = 0; i < Q; i++) {
     77         if (T[i] == 'C') {
     78             add(L[i]-1, R[i] , X[i], 0, 0, N);
     79         }
     80         else {
     81             printf("%lld
    ",sum(L[i]-1,R[i],0,0,N));
     82         }
     83     }
     84 }
     85 
     86 
     87 
     88 int main()
     89 {
     90     cin >> N >> Q;
     91 
     92     for (int i = 0; i < N; i++) {
     93         cin >> A[i];
     94     }
     95 
     96     for (int i = 0; i < Q; i++) {
     97         cin >> T[i];
     98         if (T[i] == 'C')
     99             cin >> L[i] >> R[i] >> X[i];
    100         else
    101             cin >> L[i] >> R[i];
    102     }
    103 
    104     solve();
    105 
    106     return 0;
    107 }

      1 #include <iostream>
      2 #include <vector>
      3 
      4 
      5 using namespace std;
      6 
      7 /*
      8 Sample Input
      9 10 5
     10 1 2 3 4 5 6 7 8 9 10
     11 Q 4 4
     12 Q 1 10
     13 Q 2 4
     14 C 3 6 3
     15 Q 2 4
     16 Sample Output
     17 4
     18 55
     19 9
     20 15
     21 */
     22 
     23 typedef long long ll;
     24 
     25 int n, m;
     26 
     27 const int MAX_N  = 1000010;
     28 int input[MAX_N];
     29 
     30 struct Node {
     31     int l, r;
     32     ll data;
     33 };
     34 
     35 struct Node stree[MAX_N * 4];
     36 
     37 
     38 void build(int idx, int l, int r)
     39 {
     40     stree[idx].l = l;
     41     stree[idx].r = r;
     42     if (l == r) {
     43         //叶子节点
     44         stree[idx].data = input[l];
     45         return;
     46     }
     47 
     48     int mid = (l + r) / 2;
     49     build(idx * 2, l,mid);
     50     build(idx * 2 + 1, mid + 1, r);
     51 
     52     stree[idx].data = stree[idx * 2].data + stree[idx * 2 + 1].data;
     53 }
     54 
     55 ll query(int idx, int start, int end, int l, int r)
     56 {
     57     if (l == stree[idx].l && r == stree[idx].r) {
     58         return stree[idx].data;
     59     }
     60 
     61     int mid = (start + end) / 2;
     62     if (l <= mid && r <= mid) {
     63         return query(idx * 2, start, mid, l, r);
     64     }
     65     else if (l > mid && r > mid) {
     66         return query(idx * 2 + 1, mid + 1, end, l, r);
     67     }
     68     else {
     69         ll res = 0;
     70         res += query(idx * 2 , start, mid, l, mid);
     71         res += query(idx * 2 + 1, mid + 1, end, mid + 1, r);
     72         return res;
     73     }
     74 
     75 }
     76 
     77 void add(int idx, int l, int r, int v)
     78 {
     79     if (l == r && stree[idx].l == stree[idx].r && stree[idx].l == l) {
     80         //叶子节点
     81         stree[idx].data += v;
     82         return;
     83     }
     84 
     85     int mid = (stree[idx].l + stree[idx].r) / 2;
     86     if (l <= mid && r <= mid) {
     87         add(idx * 2, l, r,v);
     88     }
     89     else if (l > mid && r > mid) {
     90         add(idx * 2 + 1, l, r,v);
     91     }
     92     else {
     93         add(idx * 2 , l, mid, v);
     94         add(idx * 2 + 1, mid+1, r, v);
     95     }
     96 
     97     stree[idx].data = stree[idx*2].data + stree[idx*2+1].data;
     98 }
     99 
    100 
    101 
    102 int main()
    103 {
    104     int n, m;
    105     cin >> n >> m;
    106     for (int i = 1; i <= n; i++) {
    107         cin >> input[i];
    108     }
    109 
    110     build(1, 1, n);
    111 
    112     for (int i = 0; i < m; i++) {
    113         char t;
    114         int l, r, v;
    115         cin >> t;
    116         if (t == 'C') {
    117             cin >> l >> r >> v;
    118             add(1, l, r, v);
    119         }
    120         else if (t == 'Q') {
    121             cin >> l >> r;
    122             cout << query(1, 1, n, l, r) << endl;
    123         }
    124     }
    125 
    126 
    127     return 0;
    128 }
    自写TLE代码
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    ios lazying load
    ios 单例模式
    ios 消息推送原理
    C#图片闪烁
    C#使窗体不显示在任务栏
    实时监测鼠标是否按下和鼠标坐标
    winfrom窗体的透明度
    C#获取屏幕的宽度和高度
    HDU 5171 GTY's birthday gift 矩阵快速幂
    HDU 5170 GTY's math problem 水题
  • 原文地址:https://www.cnblogs.com/itdef/p/12030354.html
Copyright © 2020-2023  润新知