zoukankan      html  css  js  c++  java
  • poj3468 A Simple Problem with Integers

    思路1:

    线段树区间更新。

    实现:

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 typedef long long ll;
     5 const int N = 100005;
     6 ll tree[N * 4], lazy[N * 4], a[N];
     7 int n, m;
     8 
     9 void build(int num, int l, int r)
    10 {
    11     if (l == r) { tree[num] = a[l]; return; }
    12     int m = l + r >> 1;
    13     build(num * 2, l, m);
    14     build(num * 2 + 1, m + 1, r);
    15     tree[num] = tree[num * 2] + tree[num * 2 + 1];
    16 }
    17 
    18 void pushdown(int num, int cl, int cr)
    19 {
    20     if (!lazy[num]) return;
    21     tree[num * 2] += lazy[num] * cl;
    22     tree[num * 2 + 1] += lazy[num] * cr;
    23     lazy[num * 2] += lazy[num];
    24     lazy[num * 2 + 1] += lazy[num];
    25     lazy[num] = 0;
    26 }
    27 
    28 void update(int num, int l, int r, int x, int y, ll dx)
    29 {
    30     if (x <= l && y >= r) { tree[num] += (r - l + 1) * dx; lazy[num] += dx; return; }
    31     int m = l + r >> 1;
    32     pushdown(num, m - l + 1, r - m);
    33     if (x <= m) update(num * 2, l, m, x, y, dx);
    34     if (y >= m + 1) update(num * 2 + 1, m + 1, r, x, y, dx);
    35     tree[num] = tree[num * 2] + tree[num * 2 + 1];
    36 }
    37 
    38 ll query(int num, int l, int r, int x, int y)
    39 {
    40     if (x <= l && y >= r) return tree[num];
    41     int m = l + r >> 1;
    42     pushdown(num, m - l + 1, r - m);
    43     ll ans = 0;
    44     if (x <= m) ans += query(num * 2, l, m, x, y);
    45     if (y >= m + 1) ans += query(num * 2 + 1, m + 1, r, x, y);
    46     return ans;
    47 }
    48 
    49 int main()
    50 {
    51     scanf("%d %d", &n, &m);
    52     for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
    53     getchar();
    54     build(1, 1, n);
    55     char tmp; int x, y; ll d;
    56     for (int i = 0; i < m; i++)
    57     {
    58         scanf("%c", &tmp);
    59         if (tmp == 'Q') { scanf("%d %d", &x, &y); getchar(); printf("%lld
    ", query(1, 1, n, x, y)); }
    60         else { scanf("%d %d %lld", &x, &y, &d); getchar(); update(1, 1, n, x, y, d); }
    61     }
    62     return 0;
    63 }

     思路2:

    树状数组区间更新+区间查询。

    http://blog.csdn.net/fsahfgsadhsakndas/article/details/52650026

    实现:

     1 #include <cstdio>
     2 using namespace std;
     3 typedef long long ll;
     4 const int MAXN = 100005;
     5 ll bit0[MAXN], bit1[MAXN];
     6 int n, m;
     7 
     8 int lowbit(int x) { return x & -x; }
     9 
    10 void add(ll * bit, int i, ll x)
    11 {
    12     while (i <= n) { bit[i] += x; i += lowbit(i); }
    13 }
    14 
    15 ll sum(ll * bit, int i)
    16 {
    17     ll ans = 0;
    18     while (i) { ans += bit[i]; i -= lowbit(i); }
    19     return ans;
    20 }
    21 
    22 ll query(int x)
    23 {
    24     return x * sum(bit0, x) - sum(bit1, x);
    25 }
    26 
    27 int main()
    28 {
    29     scanf("%d %d", &n, &m);
    30     char tmp; int x, y; ll d;
    31     for (int i = 1; i <= n; i++) 
    32     {
    33         scanf("%lld", &d);
    34         add(bit0, i, d);
    35         add(bit0, i + 1, -d);
    36         add(bit1, i, (i - 1) * d);
    37         add(bit1, i + 1, -i * d);
    38     }
    39     getchar();
    40     for (int i = 0; i < m; i++)
    41     {
    42         scanf("%c", &tmp);
    43         if (tmp == 'Q') 
    44         { 
    45             scanf("%d %d", &x, &y); getchar();
    46             ll r = query(y), l = query(x - 1);
    47             printf("%lld
    ", r - l);
    48         }
    49         else 
    50         { 
    51             scanf("%d %d %lld", &x, &y, &d); getchar();
    52             add(bit0, x, d);
    53             add(bit0, y + 1, -d);
    54             add(bit1, x, (x - 1) * d);
    55             add(bit1, y + 1, -y * d);
    56         }
    57     }
    58     return 0;
    59 } 

     bit1的作用就是快速(O(logN))计算((j - 1) * c[j])(1 <= j <= i)的和。甚至换成单点更新的线段树也是行得通的。

     1 #include <cstdio>
     2 #include <iostream>
     3 using namespace std;
     4 typedef long long ll;
     5 const int MAXN = 100005;
     6 ll bit[MAXN], tree[MAXN * 4];
     7 int n, m;
     8 
     9 int lowbit(int x) { return x & -x; }
    10 
    11 void add(int i, ll x)
    12 {
    13     while (i <= n) { bit[i] += x; i += lowbit(i); }
    14 }
    15 
    16 ll sum(int i)
    17 {
    18     ll ans = 0;
    19     while (i) { ans += bit[i]; i -= lowbit(i); }
    20     return ans;
    21 }
    22 
    23 void update(int num, int l, int r, int x, ll dx)
    24 {
    25     if (l == r) { tree[num] += dx; return; }
    26     int m = l + r >> 1;
    27     if (x <= m) update(num * 2, l, m, x, dx);
    28     else update(num * 2 + 1, m + 1, r, x, dx);
    29     tree[num] = tree[num * 2] + tree[num * 2 + 1];
    30 }
    31 
    32 ll query(int num, int l, int r, int x, int y)
    33 {
    34     if (x <= l && y >= r) return tree[num];
    35     int m = l + r >> 1;
    36     ll ans = 0;
    37     if (x <= m) ans += query(num * 2, l, m, x, y);
    38     if (y >= m + 1) ans += query(num * 2 + 1, m + 1, r, x, y);
    39     return ans;
    40 }
    41 
    42 ll get_ans(int x)
    43 {
    44     if (x < 1) return 0;
    45     return x * sum(x) - query(1, 1, n + 1, 1, x);
    46 }
    47 
    48 int main()
    49 {
    50     scanf("%d %d", &n, &m);
    51     char tmp; int x, y; ll d;
    52     for (int i = 1; i <= n; i++) 
    53     { 
    54         scanf("%lld", &d);
    55         add(i, d); add(i + 1, -d);
    56         update(1, 1, n + 1, i, (i - 1) * d); 
    57         update(1, 1, n + 1, i + 1, -i * d); 
    58     }
    59     getchar();
    60     for (int i = 0; i < m; i++)
    61     {
    62         scanf("%c", &tmp);
    63         if (tmp == 'Q') 
    64         { 
    65             scanf("%d %d", &x, &y); getchar();
    66             ll r = get_ans(y); 
    67             ll l = get_ans(x - 1);
    68             printf("%lld
    ", r - l);
    69         }
    70         else 
    71         { 
    72             scanf("%d %d %lld", &x, &y, &d); getchar();
    73             add(x, d);
    74             add(y + 1, -d);
    75             update(1, 1, n + 1, x, ((ll)x - 1) * d);
    76             update(1, 1, n + 1, y + 1, -(ll)y * d);
    77         }
    78     }
    79     return 0;
    80 } 
  • 相关阅读:
    数学形态学——腐蚀、膨胀、开、闭、细化
    VS2010中 报错:error C2146、error C4430 原因一:缺少CvvImage类
    帧同步和状态同步
    HTML5触摸事件演化tap事件
    screenX clientX pageX的区别
    phaser的小游戏的onInputDown问题
    phaser入手
    pixi.js 微信小游戏 入手
    正则表达式
    剖析Vue原理&实现双向绑定MVVM-2
  • 原文地址:https://www.cnblogs.com/wangyiming/p/8450421.html
Copyright © 2011-2022 走看看