zoukankan      html  css  js  c++  java
  • 【模板】线段树区间加、乘

    只需要使用两个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 }
  • 相关阅读:
    Windows Phone 8 Wallet 手机钱包 / 电子钱包
    Windows Phone 8 In app purchase 应用内购买 / 应用内支付
    Windows Phone 8 适应多屏分辨率
    Windows phone 8 基于定位的后台应用
    Windows Phone 8 Nokia地图控件
    Windows Phone 8 MDIL编译与代码混淆工具
    Windows Phone 8 近场通信 NFC / Bluetooth Proximity
    Windows Phone 8 镜头应用 Lenses for Windows Phone 8
    Windows Phone 8 与 windows 8 开发技术概览
    嵌入式成长轨迹54 【Zigbee项目】【CC2430基础实验】【系统睡眠工作状态】
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9054556.html
Copyright © 2011-2022 走看看