• 【模板】线段树区间加、乘


    只需要使用两个lazy-tag(addv, mulv)来维护,一个维护区间加,一个维护区间乘。

    注意mulv标记应在建树的时候初始化成1.

    在下传标记的时候,mulv下传时会对addv造成影响,所以修改addv时要考虑到mulv

    一定要开long long,也要检查Update, down这些函数里需要开long long的有没有开

    【代码:】

     1 //线段树维护区间加、乘
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 using namespace std;
     6 
     7 const int MAXN = 500000 + 1;
     8 const int ADD = 1, MUL = 2;
     9 
    10 int n, m, p;
    11 long long a[MAXN];
    12 struct Segment {
    13     long long sum, addv, mulv;
    14 }t[MAXN << 2];
    15 
    16 inline long long read() {
    17     long long x = 0, f = 1; char ch = getchar();
    18     while(ch < '0' || ch > '9') {
    19         if(ch == '-') f = -1;
    20         ch = getchar();
    21     }
    22     while(ch >= '0' && ch <= '9')
    23         x = (x << 3) + (x << 1) + ch - 48, ch = getchar();
    24     return x * f;
    25 }
    26 
    27 void Build(int o, int l, int r) {
    28     t[o].mulv = 1;
    29     if(l == r) t[o].sum = a[l];
    30     else {
    31         int mid = (l + r) >> 1;
    32         Build(o << 1, l, mid);
    33         Build(o << 1|1, mid + 1, r);
    34         t[o].sum = (t[o << 1].sum + t[o << 1|1].sum) % p;
    35     }
    36 }
    37 
    38 inline void down(int o, int len) {
    39     long long mul = t[o].mulv, add = t[o].addv;
    40     t[o << 1].sum = (t[o << 1].sum * mul + add * (len - (len >> 1))) % p;
    41     t[o << 1|1].sum = (t[o << 1|1].sum * mul + add * (len >> 1)) % p;
    42     t[o << 1].mulv = (t[o << 1].mulv * mul) % p;
    43     t[o << 1|1].mulv = (t[o << 1|1].mulv * mul) % p;
    44     t[o << 1].addv = (t[o << 1].addv * mul + add) % p;
    45     t[o << 1|1].addv = (t[o << 1|1].addv * mul + add) % p;
    46     t[o].mulv = 1, t[o].addv = 0;
    47 }
    48 void Update(int o, int l, int r, int ul, int ur, long long v, int fl) {
    49     if(ul <= l && r <= ur) {
    50         if(fl == 1) {
    51             t[o].sum = (t[o].sum + v * (r - l + 1)) % p;
    52             t[o].addv = (t[o].addv + v) % p;
    53         }
    54         else if(fl == 2) {
    55             t[o].sum = (t[o].sum * v) % p;
    56             t[o].mulv = (t[o].mulv * v) % p;
    57             t[o].addv = (t[o].addv * v) % p;
    58         }
    59     }
    60     else {
    61         if(t[o].mulv != 1 || t[o].addv)
    62             down(o, r - l + 1);
    63         int mid = (l + r) >> 1;
    64         if(ul <= mid) Update(o << 1, l, mid, ul, ur, v, fl);
    65         if(ur > mid) Update(o << 1|1, mid + 1, r, ul, ur, v, fl);
    66         t[o].sum = (t[o << 1].sum + t[o << 1|1].sum) % p;
    67     }
    68 }
    69 
    70 long long Query(int o, int l, int r, int ql, int qr) {
    71     if(ql <= l && r <= qr) return t[o].sum % p;
    72     int mid = (l + r) >> 1;
    73     long long ret = 0;
    74     if(t[o].mulv != 1 || t[o].addv)
    75         down(o, r - l + 1);
    76     if(ql <= mid) ret += Query(o << 1, l, mid, ql, qr);
    77     if(qr > mid) ret += Query(o << 1|1, mid + 1, r, ql, qr);
    78     return ret % p;
    79 }
    80 
    81 int main() {
    82     n = read(), m = read(), p = read();
    83     for(int i=1; i<=n; ++i)
    84         a[i] = read();
    85     Build(1, 1, n);
    86     while(m--) {
    87         long long fl = read(), x = read(), y = read();
    88         if(fl == 1) {
    89             long long k = read();
    90             Update(1, 1, n, x, y, k, MUL);
    91         }
    92         else if(fl == 2) {
    93             long long k = read();
    94             Update(1, 1, n, x, y, k, ADD);
    95         }
    96         else printf("%lld
    ", Query(1, 1, n, x, y));
    97     }
    98 }
  • 相关阅读:
    Linux平台不同解压缩命令的使用方法
    poj 1274 The Perfact Stall
    Experience Design for Sexable Forum
    JavaScript中的Array对象方法调用
    iOS9适配小结
    [Servlet&amp;JSP] HttpSession会话管理
    Android中的跨进程通信方法实例及特点分析(一):AIDL Service
    OpenCV——PS滤镜算法之Spherize 球面化(凸出效果)
    《Effective Modern C++》翻译--条款4:了解怎样查看推导出的类型
    Android开发系列之ListView
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9054556.html
Copyright © 2020-2023  润新知