• 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);
    }
  • 相关阅读:
    APPIUM Android 定位方式
    SQL Server 根据存储过程的结果集创建临时表
    Ubuntu18.04 设置开机自启动服务
    ubuntu-18.04 (各版本镜像下载) 及的环境初始化配置
    CentOS 7 编译安装PHP5.6.31
    Centos7 编译安装 MySQL 5.5.62
    Windows 2008 R2 远程桌面连接记录(客户端IP)
    CentOS crontab定时任务
    CentOS 7 安装MySql 5.5.60
    SQL Server 数据库错误码解释
  • 原文地址:https://www.cnblogs.com/forgot93/p/4275872.html
Copyright © 2020-2023  润新知