zoukankan      html  css  js  c++  java
  • P1438 无聊的数列

    原题链接

    • 题意和思路:挺有意思的一道题,就是两个操作,第一个操作是在 (l)(r) 的区间上加上首项为 (k),公比为 (d) 的等差序列。第二个操作是询问第 (x) 个数是多少。其实就是区间修改 (+) 区间查询,操作一就是在 (l) 上加上 (k),然后在 (l + 1)(r) 上加上 (d),然后在 (r + 1) 上减去 ((r-(l + 1)-1) imes d + k)。需要注意的是,小心要是 (r + 1 > n) 会出现奇怪的错误,所以要细心边界。
    • 代码:
    #include <cstdio>
    #include <iostream>
    using namespace std;
    const ll inf = 0x3f3f3f3f;
    const ll N = 1e5 + 9;
    int a[N];
    int sum[N];
    struct segment_tree {
        struct node {
            int l, r, L, R, data, lazy;
        } tr[N << 2];
        inline void pushup(int p) {tr[p].data = tr[tr[p].l].data + tr[tr[p].r].data;}
        inline void pushdown(int p) {
            if (tr[p].lazy == 0) return;
            tr[tr[p].l].data += (tr[tr[p].l].R - tr[tr[p].l].L + 1) * tr[p].lazy;
            tr[tr[p].r].data += (tr[tr[p].r].R - tr[tr[p].r].L + 1) * tr[p].lazy;
            tr[tr[p].l].lazy += tr[p].lazy;
            tr[tr[p].r].lazy += tr[p].lazy;
            tr[p].lazy = 0;
            return;
        }
        inline void build(int l, int r, int p) {
            tr[p].L = l, tr[p].R = r;
            tr[p].l = p << 1;
            tr[p].r = p << 1 | 1;
            if (l == r) {
                tr[p].data = a[l];
                return;
            }
            int mid = l + r >> 1;
            build(l, mid, tr[p].l);
            build(mid + 1, r, tr[p].r);
            pushup(p);
        }
        inline void add(int l, int r, int num, int p) {
            if (tr[p].L >= l && tr[p].R <= r) {
                tr[p].data += num * (tr[p].R - tr[p].L + 1);
                tr[p].lazy += num;
                return;
            }
            pushdown(p);
            int mid = l + r >> 1;
            if (tr[tr[p].l].R >= l) add(l, r, num, tr[p].l);
            if (tr[tr[p].r].L <= r) add(l, r, num, tr[p].r);
            pushup(p);
        }
        inline int ask(int l, int r, int p) {
            if (tr[p].L >= l && tr[p].R <= r) {
                return tr[p].data;
            }
            pushdown(p);
            int ret = 0;
            if (tr[tr[p].l].R >= l) ret += ask(l, r, tr[p].l);
            if (tr[tr[p].r].L <= r) ret += ask(l, r, tr[p].r);
            return ret;
        }
    } T;
    signed main() {
        int n, m;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]), sum[i] = sum[i - 1] + a[i];
        T.build(1, n, 1);
        while (m--) {
            int op;
            scanf("%d", &op);
            if (op == 1) {
                int l, r, k, d;
                scanf("%d%d%d%d", &l, &r, &k, &d);
                T.add(l, l, k, 1);
                if (r != l) T.add(l + 1, r, d, 1);
                int sub = (r - (l + 1) + 1) * d + k;
                if (r + 1 <= n)
                T.add(r + 1, r + 1, -sub, 1);
            } else {
                int x;
                scanf("%d", &x);
                printf("%d
    ", T.ask(1, x, 1) - sum[x - 1]);
            }
        }
    }
    
  • 相关阅读:
    今天地震了(有震感)...
    上班了!
    C++ 中explicit的作用
    DoModal 函数的用法
    [导入]C++ GUi 选择
    [导入]C++资源之不完全导引(完整版)[转]
    [导入]The GUI Toolkit, Framework Page
    [导入]C/C++中调用SQLITE3的基本步骤
    ACM
    牛客NOIP暑期七天营提高组5+普及组5
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/14688361.html
Copyright © 2011-2022 走看看