• 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]);
            }
        }
    }
    
  • 相关阅读:
    JS日期显示格式 yyyy-MM-dd hh:mm:ss
    Html.Partial和Html. RenderPartial
    $.ajax()详解
    B/S 类项目改善
    yaml
    跟我学SpringMVC目录汇总贴、PDF下载、源码下载
    全网最全ASP.NET MVC 教程汇总
    持续集成实践
    http://blog.jobbole.com/50603/#comment-153933
    Java代码优化(转)
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/14688361.html
Copyright © 2020-2023  润新知