首页 > 其他分享 >lgP1253 扶苏的问题

lgP1253 扶苏的问题

时间:2024-07-14 12:08:20浏览次数:7  
标签:std Info const int void 扶苏 问题 info lgP1253

给定长度为n的序列A,有如下3种操作:

  • 1 l r x,将区间[l,r]中的每个数都修改为x。
  • 2 l r x,将区间[l,r]中的每个数都加上x。
  • 3 l r,查询区间[l,r]内的最大值。

分析:设置2个懒标记,先处理赋值标记,再处理增加标记。

#include <bits/stdc++.h>
using llong = long long;

const llong inf = 1e18;

template<class Info, class Tag>
struct LazySegmentTree {
    int n;
    std::vector<Info> info;
    std::vector<Tag> tag;
    LazySegmentTree():n(0) {}
    LazySegmentTree(int _n, Info v=Info()) {
        init(_n, v);
    }
    template<class T>
    LazySegmentTree(std::vector<T> v) {
        init(v);
    }
    void init(int _n, Info v=Info()) {
        init(std::vector<Info>(_n, v));
    }
    template<class T>
    void init(std::vector<T> v) {
        n = v.size();
        info.assign(4 << std::__lg(n), Info());
        tag.assign(4 << std::__lg(n), Tag());
        std::function<void(int,int,int)> build = [&](int x, int l, int r) {
            if (l + 1 == r) {
                info[x] = v[l];
                return;
            }
            int m = (l + r) / 2;
            build(2*x+1, l, m);
            build(2*x+2, m, r);
            pushup(x);
        };
        build(0, 0, n);
    }
    void pushup(int x) {
        info[x] = info[2*x+1] + info[2*x+2];
    }
    void apply(int x, const Tag &t) {
        info[x].apply(t);
        tag[x].apply(t);
    }
    void pushdown(int x) {
        apply(2*x+1, tag[x]);
        apply(2*x+2, tag[x]);
        tag[x] = Tag();
    }
    void assign(int x, int l, int r, int p, const Info &v) {
        if (l + 1 == r) {
            info[x] = v;
            return;
        }
        int m = (l + r) / 2;
        pushdown(x);
        if (p < m) {
            assign(2*x+1, l, m, p, v);
        } else {
            assign(2*x+2, m, r, p, v);
        }
        pushup(x);
    }
    void assign(int p, const Info &v) {
        assign(0, 0, n, p, v);
    }
    void add(int x, int l, int r, int p, const Info &v) {
        if (l + 1 == r) {
            info[x] += v;
            return;
        }
        int m = (l + r) / 2;
        pushdown(x);
        if (p < m) {
            add(2*x+1, l, m, p, v);
        } else {
            add(2*x+2, m, r, p, v);
        }
        pushup(x);
    }
    void add(int p, const Info &v) {
        add(0, 0, n, p, v);
    }
    Info rangeQuery(int x, int l, int r, int L, int R) {
        if (R <= l || r <= L) {
            return Info();
        }
        if (L <= l && r <= R) {
            return info[x];
        }
        int m = (l + r) / 2;
        pushdown(x);
        return rangeQuery(2*x+1, l, m, L, R) + rangeQuery(2*x+2, m, r, L, R);
    }
    Info rangeQuery(int L, int R) {
        return rangeQuery(0, 0, n, L, R);
    }
    void rangeApply(int x, int l, int r, int L, int R, const Tag &t) {
        if (R <= l || r <= L) {
            return;
        }
        if (L <= l && r <= R) {
            apply(x, t);
            return;
        }
        int m = (l + r) / 2;
        pushdown(x);
        rangeApply(2*x+1, l, m, L, R, t);
        rangeApply(2*x+2, m, r, L, R, t);
        pushup(x);
    }
    void rangeApply(int L, int R, const Tag &t) {
        return rangeApply(0, 0, n, L, R, t);
    }
    template<class F>
    int findFirst(int x, int l, int r, int L, int R, F && pred) {
        if (R <= l || r <= L) {
            return -1;
        }
        if (L <= l && r <= R && !pred(info[x])) {
            return -1;
        }
        if (l + 1 == r) {
            return l;
        }
        int m = (l + r) / 2;
        pushdown(x);
        int res = findFirst(2*x+1, l, m, L, R, pred);
        if (res == -1) {
            res = findFirst(2*x+2, m, r, L, R, pred);
        }
        return res;
    }
    template<class F>
    int findFirst(int L, int R, F &&pred) {
        return findFirst(0, 0, n, L, R, pred);
    }
    template<class F>
    int findLast(int x, int l, int r, int L, int R, F &&pred) {
        if (R <= l || r <= L) {
            return -1;
        }
        if (L <= l && r <= R && !pred(info[x])) {
            return -1;
        }
        if (l + 1 == r) {
            return l;
        }
        int m = (l + r) / 2;
        pushdown(x);
        int res = findLast(2*x+2, m, r, L, R, pred);
        if (res == -1) {
            res = findLast(2*x+1, l, m, L, R, pred);
        }
        return res;
    }
    template<class F>
    int findLast(int L, int R, F &&pred) {
        return findLast(0, 0, n, L, R, pred);
    }
    void print(int x, int l, int r) {
        std::cerr << x << "(" << l << "," << r << ") " << info[x] << " " << tag[x] << "\n";
        if (l + 1 < r) {
            int m = (l + r) / 2;
            print(2*x+1, l, m);
            print(2*x+2, m, r);
        }
    }
    void print() {
        std::cerr << "-----------------------------\n";
        print(0, 0, n);
    }
};

struct Tag {
    llong set;
    llong add;
    Tag(llong s=inf, llong a=inf):set(s),add(a) {}
    void apply(Tag t) {
        if (t.set != inf) {
            set = t.set;
            add = inf;
        }
        if (t.add != inf) {
            if (add == inf) {
                add = t.add;
            } else {
                add += t.add;
            }
        }
    }
    friend std::ostream& operator<<(std::ostream &out, Tag &tag) {
        out << "tag:(" << tag.set << "," << tag.add << ")";
        return out;
    }
};

struct Info {
    llong max;
    Info(llong a=-inf):max(a) {}
    void apply(Tag t) {
        if (t.set != inf) {
            max = t.set;
        }
        if (t.add != inf) {
            max += t.add;
        }
    }
    friend Info operator+(const Info &a, const Info &b) {
        Info ans;
        ans.max = std::max(a.max, b.max);
        return ans;
    }
    friend std::ostream& operator<<(std::ostream &out, Info &info) {
        out << "info:(" << info.max << ")";
        return out;
    }
};

void solve() {
    int n, m;
    std::cin >> n >> m;
    std::vector<llong> A(n);
    for (int i = 0; i < n; i++) {
        std::cin >> A[i];
    }
    LazySegmentTree<Info,Tag> tr(A);
    for (int i = 0; i < m; i++) {
        int op, l, r, x;
        std::cin >> op >> l >> r;
        if (op == 1) {
            std::cin >> x;
            tr.rangeApply(l-1, r, Tag(x, inf));
        } else if (op == 2) {
            std::cin >> x;
            tr.rangeApply(l-1, r, Tag(inf, x));
        } else if (op == 3) {
            std::cout << tr.rangeQuery(l-1, r).max << "\n";
        }
    }
}

int main() {
    std::cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}

标签:std,Info,const,int,void,扶苏,问题,info,lgP1253
From: https://www.cnblogs.com/chenfy27/p/18301328

相关文章

  • 计算机网络 TCP粘包问题
    什么是粘包?粘包是指的是数据和数据之间没有没有明确的分界线,导致不能够正确的传输数据(只有TCP会粘包UDP永远不会粘包),粘包问题只针对于一切字节流的协议。TCP也可以称为流式协议,UDP称为数据报式协议。对于流式协议:发送端可以1K1K的发送数据,接收端可以2k2k的提取数据,也可以......
  • Java优雅使用线程池连接SFTP进行文件上传下载 解决请求量大问题
    Java优雅使用线程池连接SFTP进行文件上传下载解决请求量大问题使用FTP连接池降低资源消耗,提高响应速率为什么要使用线程池连接SFTP呢?在Java中使用线程池来连接SFTP(SecureFileTransferProtocol)工具的原因主要与性能、资源管理和效率有关。以下是一些关键原因:资源管......
  • Windows11系统System.Runtime.Serialization.dll文件丢失问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个System.Runtime.Serialization.dll文件(挑选......
  • Windows11系统System.Resources.Writer.dll文件丢失问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个System.Resources.Writer.dll文件(挑选合适......
  • Resid核心问题总结(三)
    什么是缓存击穿?该如何解决缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。缓存击穿的话,设置热点数据永远不过期。或者加上互斥锁就能搞定了。......
  • 问题 I: 深入浅出学算法051-均分纸牌
    题目描述有N堆纸牌,编号分别为1,2,…,N。每堆上有若干张,但纸牌总数必为N的倍数。可以在任一堆上取若干张纸牌,然后移动。       移牌规则为:在编号为1堆上取的纸牌,只能移到编号为2的堆上;在编号为N的堆上取的纸牌,只能移到编号为N-1的堆上;其他堆上取的纸牌,可......
  • 约数问题(模板)
    869.试除法求约数-AcWing题库#include<bits/stdc++.h>usingnamespacestd;vector<int>solve(intx){vector<int>ans;for(inti=1;i<=x/i;i++){if(x%i==0){ans.push_back(i);if(x/i!=i)a......
  • 最短路问题
    最短路问题writeashortintroduce朴素做法writesomethingCode1Code多源最短路比较好于理解与编写的是Floyd算法。Code2#include<iostream>#include<iomanip>#include<string.h>usingnamespacestd;intn,m;intg[105][105];voidaddedge(intu,intv,int......
  • 探索贪心算法:解决优化问题的高效策略
    贪心算法是一种在每一步选择中都采取当前最佳选择的算法,以期在整体上达到最优解。它广泛应用于各种优化问题,如最短路径、最小生成树、活动选择等。本文将介绍贪心算法的基本概念、特点、应用场景及其局限性。贪心算法的基本概念贪心算法的核心思想是局部最优策略,即在每一步选择......
  • N1盒子挂载磁盘-解决盒子重启后无法自动挂载问题
    MarkdownExampleN1盒子挂载磁盘挂载步骤:step1step2如果提示挂载已存在、就先卸载挂载分区step3回到首页重新挂载step4此时已经挂载成功、但是默认的挂载名是随机的如:usb1-1这样的就会存在一个问题、当N1盒子重启的时候就会不能自动挂载所以要重新修改挂载......