zoukankan      html  css  js  c++  java
  • BZOJ 1798:

    6:
          LAZY 线段树有乘法的更新
       #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    const int maxn = 101000;
    long long value[maxn], mod;
    struct SegNode {
        int left, right;
        long long sum, add, mul;
        int mid() {
            return (left + right) >> 1;
        }
        int size() {
            return right - left + 1;
        }
    };
    struct SegmentTree {
        SegNode tree[maxn*5];
        void pushUp(int idx) {
            tree[idx].sum = (tree[idx<<1].sum + tree[idx<<1|1].sum) % mod;
        }
        void pushDown(int idx) {
            tree[idx<<1].add = (tree[idx].mul % mod * tree[idx<<1].add % mod + tree[idx].add) % mod;
            tree[idx<<1|1].add = (tree[idx].mul % mod * tree[idx<<1|1].add % mod + tree[idx].add) % mod;
            tree[idx<<1].mul = tree[idx<<1].mul % mod * tree[idx].mul % mod;
            tree[idx<<1|1].mul = tree[idx<<1|1].mul % mod * tree[idx].mul % mod;
            tree[idx<<1].sum = (tree[idx<<1].sum % mod * tree[idx].mul % mod
                + tree[idx<<1].size() * tree[idx].add % mod) % mod;
            tree[idx<<1|1].sum = (tree[idx<<1|1].sum % mod * tree[idx].mul % mod
                + tree[idx<<1|1].size() * tree[idx].add % mod) % mod;
            tree[idx].add = 0;
            tree[idx].mul = 1;
        }
        void build(int left, int right, int idx) {
            tree[idx].left = left;
            tree[idx].right = right;
            tree[idx].sum = 0;
            tree[idx].mul = 1;
            tree[idx].add = 0;
            if (left == right) {
                tree[idx].sum = value[left] % mod;
                return ;
            }
            int mid = tree[idx].mid();
            build(left, mid, idx<<1);
            build(mid+1, right, idx<<1|1);
            pushUp(idx);
        }
        void update(int left, int right, int idx, int opt, long long val) {
            if (tree[idx].left == left && tree[idx].right == right) {
                if (opt == 1) {
                    tree[idx].add = (tree[idx].add + val) % mod;
                    tree[idx].sum = (tree[idx].sum + tree[idx].size() % mod * val) % mod;
                } else {
                    tree[idx].add = tree[idx].add % mod * val % mod;
                    tree[idx].mul = tree[idx].mul % mod * val % mod;
                    tree[idx].sum = tree[idx].sum % mod * val % mod;
                }
                return ;
            }
            pushDown(idx);
            int mid = tree[idx].mid();
            if (right <= mid)
                update(left, right, idx<<1, opt, val);
            else if (left > mid)
                update(left, right, idx<<1|1, opt, val);
            else {
                update(left, mid, idx<<1, opt, val);
                update(mid+1, right, idx<<1|1, opt, val);
            }
            pushUp(idx);
        }
        long long query(int left, int right, int idx) {
            if (tree[idx].left == left && tree[idx].right == right) {
                return tree[idx].sum % mod;
            }
            pushDown(idx);
            int mid = tree[idx].mid();
            if (right <= mid)
                return query(left, right, idx<<1);
            else if (left > mid)
                return query(left, right, idx<<1|1);
            else {
                return (query(left, mid, idx<<1) % mod + query(mid+1, right, idx<<1|1));
            }
        }
    };
    SegmentTree tree;
    int n, m;
    void init() {
        scanf("%d %lld", &n, &mod);
        for (int i = 1; i <= n; i++)
            scanf("%lld", &value[i]);
        tree.build(1, n, 1);
    }
  • 相关阅读:
    linux 系统运维工具13款
    Django2.0 分页的应用
    jvm优化
    SSH-key 在Windows下如何生成公钥和私钥
    申请Let’s Encrypt免费证书,给自己网站增加https访问
    wordpress上传主题以及安装插件 出现ftp的问题解决方案
    php压缩文件
    linux下 如何切换到root用户
    TP3.2.3框架隐藏Home模块以及index.php入口文件的方法
    PHP打开错误提示和关闭错误提示的方法
  • 原文地址:https://www.cnblogs.com/forgot93/p/4275872.html
Copyright © 2011-2022 走看看