zoukankan      html  css  js  c++  java
  • P3373 线段树2(多重标记线段树)题解

    题意:

    操作有:区间加,区间乘,区间询问求和

    思路:

    设一个数为(m*sum+a),加就变成了(m*sum+a+a_2),乘就变成了(m*m_2*sum+a*m_2),所以我们设两个标记(mul)表示乘,(add)表示加,然后如上转化。

    代码:

    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<cmath>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<cstring>
    #include<sstream>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 100000 + 5;
    const int INF = 0x3f3f3f3f;
    const ull seed = 131;
    const ll MOD = 10007;
    using namespace std;
    ll n, m, p;
    ll sum[maxn << 2], add[maxn << 2], mul[maxn << 2];
    int a[maxn];
    void pushup(int rt){
        sum[rt] = (sum[rt << 1] + sum[rt << 1 | 1]) % p;
    }
    void pushdown(int rt, int l, int r){
        int m = (l + r) >> 1;
        sum[rt << 1] = (sum[rt << 1] * mul[rt] + add[rt] * (m - l + 1)) % p;
        sum[rt << 1 | 1] = (sum[rt << 1 | 1] * mul[rt] + add[rt] * (r - m)) % p;
        add[rt << 1] = (add[rt << 1] * mul[rt] + add[rt]) % p;
        add[rt << 1 | 1] = (add[rt << 1 | 1] * mul[rt] + add[rt]) % p;
        mul[rt << 1] = mul[rt << 1] * mul[rt] % p;
        mul[rt << 1 | 1] = mul[rt << 1 | 1] * mul[rt] % p;
        add[rt] = 0;
        mul[rt] = 1;
    }
    void build(int l, int r, int rt){
        add[rt] = 0;
        mul[rt] = 1;
        if(l == r){
            sum[rt] = a[l];
            return;
        }
        int m = (l + r) >> 1;
        build(l, m, rt << 1);
        build(m + 1, r, rt << 1 | 1);
        pushup(rt);
    }
    void update(int L, int R, int l, int r, int v, int op, int rt){
        if(L <= l && R >= r){
            if(op == 2){
               add[rt] = (add[rt] + v) % p;
               sum[rt] = (sum[rt] + (r - l + 1) * v) % p;
            }
            else{
               add[rt] = add[rt] * v % p;
               mul[rt] = mul[rt] * v % p;
               sum[rt] = sum[rt] * v % p;
            }
            return;
        }
        pushdown(rt, l, r);
        int m = (l + r) >> 1;
        if(L <= m)
            update(L, R, l, m, v, op, rt << 1);
        if(R > m)
            update(L, R, m + 1, r, v, op, rt << 1 | 1);
        pushup(rt);
    }
    ll query(int L, int R, int l, int r, int rt){
        if(L <= l && R >= r){
            return sum[rt];
        }
        pushdown(rt, l, r);
        int m = (l + r) >> 1;
        ll ret = 0;
        if(L <= m)
            ret += query(L, R, l, m, rt << 1);
        if(R > m)
            ret += query(L, R, m + 1, r, rt << 1 | 1);
        return ret % p;
    }
    int main(){
        scanf("%lld%lld%lld", &n, &m, &p);
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
        build(1, n, 1);
        while(m--){
            int op, x, y, k;
            scanf("%d%d%d", &op, &x, &y);
            if(op != 3) scanf("%d", &k);
            if(op == 1) update(x, y, 1, n, k, 1, 1);
            else if(op == 2) update(x, y, 1, n, k, 2, 1);
            else printf("%lld
    ", query(x, y, 1, n, 1));
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    FMXUI TEXTVIEW代码设置IMAGEINDEX
    WIN10无法识别安卓设备,提示Windows 无法验证此设备所需的驱动程序的数字签名
    FMX Android ZIP解压中文乱码
    Fmx在android下InputBox输入框点击Cancel取消按钮后报异常
    BLUEHOST香港主机FTP连接不上解决办法
    Delphi abstract error异常
    DELPHI FMX IOS模拟器调试时出现No SDKs could be found
    VM安装OSX进度条一半时卡住不动,【附】OSX10.10 ISO镜像文件
    Tengine 安装配置全过程(nginx 同理)
    php 运行的四种模式
  • 原文地址:https://www.cnblogs.com/KirinSB/p/11408293.html
Copyright © 2011-2022 走看看