• acwing 242. 一个简单的整数问题


    地址 https://www.acwing.com/problem/content/248/

    给定长度为N的数列A,然后输入M行操作指令。

    第一类指令形如“C l r d”,表示把数列中第l~r个数都加d。

    第二类指令形如“Q X”,表示询问数列中第x个数的值。

    对于每个询问,输出一个整数表示答案。

    输入格式

    第一行包含两个整数N和M。

    第二行包含N个整数A[i]。

    接下来M行表示M条指令,每条指令的格式如题目描述所示。

    输出格式

    对于每个询问,输出一个整数表示答案。

    每个答案占一行。

    数据范围

    1N,M1051≤N,M≤105,
    |d|10000|d|≤10000,
    |A[i]|1000000000

    输入样例:

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

    输出样例:

    4
    1
    2
    5

     区间修改 单点询问  利用差分的树状数组

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    
    using namespace std;
    
    const int N = 100010;
    
    typedef long long ll;
    typedef long long LL;
    
    int n, m;
    int a[N];
    ll tr[N];
    
    int lowbit(int x) {
        return x & -x;
    }
    
    void add(int x, int c)
    {
        for (int i = x; i <= n; i += lowbit(i)) tr[i] += c;
    }
    
    
    ll sum(int x)
    {
        ll res = 0;
        for (int i = x; i; i -= lowbit(i)) res += tr[i];
        return res;
    }
    
    
    int main()
    {
        scanf("%d %d", &n, &m);
    
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    
        for (int i = 1; i <= n; i++) add(i, a[i] - a[i - 1]);
    
        while (m--) {
            char op[2];
            int l, r, d;
            scanf("%s%d",op,&l);
    
            if (*op == 'C') {
                scanf("%d%d", &r, &d);
                add(l, d); add(r + 1, -d);
            }
            else {
                printf("%lld
    ",sum(l));
            }
        }
    
        return 0;
    }

    线段树 lazy模板

    #include <iostream>
    #include <algorithm>
    #include <string>
    
    using namespace std;
    
    /*
    给定长度为N的数列A,然后输入M行操作指令。
    
    第一类指令形如“C l r d”,表示把数列中第l~r个数都加d。
    
    第二类指令形如“Q X”,表示询问数列中第x个数的值。
    
    对于每个询问,输出一个整数表示答案。
    
    输入格式
    第一行包含两个整数N和M。
    
    第二行包含N个整数A[i]。
    
    接下来M行表示M条指令,每条指令的格式如题目描述所示。
    
    输出格式
    对于每个询问,输出一个整数表示答案。
    
    每个答案占一行。
    
    数据范围
    1≤N,M≤105,
    |d|≤10000,
    |A[i]|≤1000000000
    输入样例:
    10 5
    1 2 3 4 5 6 7 8 9 10
    Q 4
    Q 1
    Q 2
    C 1 6 3
    Q 2
    输出样例:
    4
    1
    2
    5
    */
    const int maxn = 1e5 + 6;
    int n;
    int a[maxn];
    int q;
    
    struct node {
        int l, r;
        long long sum, lazy;
        void update(long long x) {
            sum += 1ll * (r - l + 1)*x;
            lazy += x;
        }
    }tree[maxn*4];
    
    void push_up(int x) {
        tree[x].sum = tree[x << 1].sum + tree[x << 1 | 1].sum;
    }
    
    void push_down(int x)
    {
        int lazyval = tree[x].lazy;
        if (lazyval) {
            tree[x << 1].update(lazyval);
            tree[x << 1 | 1].update(lazyval);
            tree[x].lazy = 0;
        }
    
    }
    
    void build(int x, int l, int r) {
        tree[x].l = l; tree[x].r = r;
        tree[x].sum = tree[x].lazy = 0;
        if (l == r) {
            tree[x].sum = a[l];
        }
        else {
            int mid = (l + r) / 2;
            build(x << 1, l, mid);
            build(x << 1 | 1, mid + 1, r);
            push_up(x);
        }
    }
    
    void update(int x, int l, int r, long long val)
    {
        int L = tree[x].l, R = tree[x].r;
        if (l <= L && R <= r) {
            tree[x].update(val);
        }
        else {
            push_down(x);
            int mid = (L + R) / 2;
            if (mid >= l)  update(x << 1, l, r, val);
            if (r > mid) update(x << 1 | 1, l, r, val);
            push_up(x);
        }
    }
    
    long long query(int x, int l, int r)
    {
        int L = tree[x].l, R = tree[x].r;
        if (l <= L && R <= r) {
            return tree[x].sum;
        }
        else {
            push_down(x);
            long long ans = 0;
            int mid = (L + R) / 2;
            if (mid >= l)  ans += query(x << 1, l, r);
            if (r > mid)  ans += query(x << 1 | 1, l, r);
            push_up(x);
            return ans;
        }
    }
    
    
    
    
    int main()
    {
        cin >> n >> q;
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
        }
        build(1, 1, n);
        
        for (int i = 1; i <= q; i++) {
            string s;
            int l, r, d, q;
            cin >> s;
            if (s == "Q") {
                cin >> q;
                cout << query(1, q, q) << endl;
            }
            else {
                cin >> l >> r >> d;
                update(1, l, r, d);
            }
        }
    
        return 0;
    }
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    JS中的间歇(周期)调用setInterval()与超时(延迟)调用setTimeout()相关总结
    jQuery中的height()、innerheight()、outerheight()的区别总结
    单行及多行文本溢出以省略号显示的方法总结
    Android图片缩放 指定尺寸
    Android开源SlidingMenu的使用
    说说Android应用的persistent属性
    Android使用init.rc触发脚本实现隐藏内置应用
    android之实现上下左右翻页效果
    Android中播放声音
    Android中StatFs获取系统/sdcard存储(剩余空间)大小
  • 原文地址:https://www.cnblogs.com/itdef/p/12163355.html
Copyright © 2020-2023  润新知