chenfy27的刷题记录

导航

luoguP3870 开关

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

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

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

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

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

// LazySegmentTree模板...

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;
}

posted on 2024-07-14 12:00  chenfy27  阅读(12)  评论(0)    收藏  举报