首页 > 其他分享 >lgP3870 开关

lgP3870 开关

时间:2024-07-14 12:08:56浏览次数:8  
标签:info std lgP3870 int pred void Info 开关

有n盏灯,从左到右编号依次为1~n,有m次操作:

  • 1 a b,表示修改区间[a,b]内灯的状态。
  • 2 a b,查询区间[a,b]内有多少盏灯是打开的。

初始时所有灯都是关着的。

分析:线段树维护区间内打开灯的数目,涉及到区间更新,要用懒标记。

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

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]; // fixme
                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 modify(int x, int l, int r, int p, const Info &v) {
        if (l + 1 == r) {
            info[x] = v; //fixme
            return;
        }
        int m = (l + r) / 2;
        pushdown(x);
        if (p < m) {
            modify(2*x+1, l, m, p, v);
        } else {
            modify(2*x+2, m, r, p, v);
        }
        pushup(x);
    }
    void modify(int p, const Info &v) {
        modify(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 dfs(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;
            dfs(2*x+1, l, m);
            dfs(2*x+2, m, r);
        }
    }
    void dfs() {
        std::cerr << "========================\n";
        dfs(0, 0, n);
    }
};

struct Tag {
    int flip;
    Tag(int t=0):flip(t) {}
    void apply(Tag t) {
        flip ^= t.flip;
    }
    friend std::ostream& operator<<(std::ostream &out, Tag &tag) {
        out << "tag:(flip:" << tag.flip << ")";
        return out;
    }
};

struct Info {
    int cnt;
    int len;
    Info(int s=0):cnt(s),len(1) {}
    void apply(Tag t) {
        if (t.flip) {
            cnt = len - cnt;
        }
    }
    friend Info operator+(const Info &a, const Info &b) {
        Info ans;
        ans.cnt = a.cnt + b.cnt;
        ans.len = a.len + b.len;
        return ans;
    }
    friend std::ostream& operator<<(std::ostream &out, Info &info) {
        out << "info:(cnt:" << info.cnt << ",len:" << info.len << ")";
        return out;
    }
};

void solve() {
    int n, m;
    std::cin >> n >> m;
    std::vector<int> A(n);
    LazySegmentTree<Info,Tag> tr(A);
    for (int i = 0; i < m; i++) {
        int c, a, b;
        std::cin >> c >> a >> b;
        if (c == 0) {
            tr.rangeApply(a-1, b, Tag(1));
        } else if (c == 1) {
            std::cout << tr.rangeQuery(a-1, b).cnt << "\n";
        }
    }
}

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

标签:info,std,lgP3870,int,pred,void,Info,开关
From: https://www.cnblogs.com/chenfy27/p/18301325

相关文章

  • Windows 10防火墙掌控指南:轻松开关,安全随心
        在数字时代,网络安全已成为不容忽视的关键议题。作为个人电脑的守护者,Windows10自带的防火墙系统在拦截恶意攻击、保护隐私方面发挥着至关重要的作用。然而,对于许多用户而言,如何正确地打开或关闭Windows防火墙,以适应不同的网络环境和安全需求,仍是一个亟待解答的问......
  • 开关电源详解
    一、开关电源的概述1.定义与简介开关电源(Switched-ModePowerSupply,SMPS)是一种通过高频开关器件(如晶体管、MOSFET)进行电能转换的电源装置。与传统的线性电源相比,开关电源具有转换效率高、体积小、重量轻、输入电压范围宽等优点,因此在现代电子设备中得到广泛应用。2.发展......
  • P10449 费解的开关
    费解的开关题目描述你玩过“拉灯”游戏吗?\(25\)盏灯排成一个\(5\times5\)的方形。每一个灯都有一个开关,游戏者可以改变它的状态。每一步,游戏者可以改变某一个灯的状态。游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。我们用数......
  • 开关电源三种基本拓扑的总结及其应用实例
    一、开关电源拓扑基础传统的开关电源拓扑可分为三种:Buck(降压型)、Boost(升压型)、Buck-Boost(升降压型)。对这三种拓扑归纳如下。1.1Buck-BoostBuck-Boost根据地参考点的位置可以进一步细分为正对负型和负对正型。升降压型拓扑的端口特性为:输入与输出反相;可升压也可降压。电......
  • 《安富莱嵌入式周报》第339期:单片机运行苹果早期Mac系统模拟器,2GHz示波器有源探头,下一
    周报汇总地址:http://www.armbbs.cn/forum.php?mod=forumdisplay&fid=12&filter=typeid&typeid=104 视频版https://www.bilibili.com/video/BV1Kf421Q7Lh目录1、开源2GHz的示波器有源探头2、模拟矩阵开关面包板Jumperless推出下一代JumperlessV53、软件相关(1)Swifton......
  • Arduino 驱动倾斜开关传感器
    下面是使用ArduinoUnoR3驱动倾斜开关传感器模块的详细说明、接线图和代码示例。所需材料ArduinoUnoR3倾斜开关传感器模块面包板和连接线接线步骤供电和地线连接:将ArduinoUno的5V引脚连接到倾斜开关传感器模块的VCC引脚。将ArduinoUno的GND引脚连接到倾斜开关传......
  • windows下使用bat定时开关windows的一项服务
    原文链接:windows下使用bat定时开关windows的一项服务–每天进步一点点(longkui.site)一个需求要求每天定时开关一项服务。假如这项服务是Redis。那么用什么指令呢?其实很简单,用下方两个指令就可以开关某个服务:netstart服务名netstop服务名我们用管理员方式打开cmd(比......
  • 零停机部署——特征开关(Feature Toggles)的应用
    引言在现代软件开发和部署中,零停机部署技术是实现高可用性和无缝用户体验的关键。本文将讨论功能开发开关(FeatureToggles)的类型并分析它们的优缺点,同时提供相关的例子和演示。PS:https://github.com/WeiXiao-Hyy/blog整理了后端开发的知识网络,欢迎Star!功能开发(Featu......
  • 提供一系列RF和微波:MMA041AA、MMA040AA(射频放大器)MMA022AA,MMS008AA射频开关
    MMA041AA是一款低噪声分布式放大器芯片,工作频率范围为DC至26GHz。该放大器提供18dB的平坦增益、3.2dB噪声系数和22dBm输出功率(1dBm增益压缩)。MMA041AA放大器具有内部匹配50ω的RFI/O,便于集成到MCM中。非常适合测试仪器和通信基础设施应用。特性宽带性能:DC至26GHz高增益......
  • 八路DI八路DO开关量输入输出 远程IO模块 Modbus TCP数据采集模块 YL90
    特点:●八路开关量输入,八路开关量输出● DI状态变化自动发送状态数据,可以捕获脉冲● 采用Socket自由协议编程简单、轻松应用● 开关量毫秒级响应速度适应多种场合● 内置网页功能,可以通过网页查询与控制● 同时也支持ModbusTCP通讯协议● 宽电源供电范围:8~32......