P2184 贪婪大陆
题目描述
小 FF 最后一道防线是一条长度为
输入格式
第一行为两个整数
接下来有
- 若
,则表示 SCV 在 这段区间布上一种地雷; - 若
,则表示小 FF 询问当前 区间总共有多少种地雷。
输出格式
对于小 FF 的每次询问,输出一个答案(单独一行),表示当前区间地雷总数。
Solution
线段树/树状数组/差分思想
本题就是属于线段树不太好做,树状数组有优势的题目
实际上是单点修改/区间查询的题目
C41 线段树+差分 P2184 贪婪大陆_哔哩哔哩_bilibili
求区间
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define ls u<<1
#define rs u<<1|1
const int N = 100005;
int n, m;
struct tree {
int l, r, sum[2];
}tr[N * 4];
//sum[0]:区间起点数, sum[1]:区间终点数
void pushup(int u, int k) { //上传
tr[u].sum[k] = tr[ls].sum[k] + tr[rs].sum[k];
}
void build(int u, int l, int r) { //建树
tr[u] = {l,r,0,0};
if (l == r)return;
int mid = (l + r) >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
}
void change(int u, int x, int k) { //点修
if (tr[u].l == tr[u].r) {
tr[u].sum[k]++; return;
}
if (x <= tr[ls].r) change(ls, x, k);
else change(rs, x, k);
pushup(u, k);
}
int query(int u, int x, int y, int k) { //区查
if (x > tr[u].r || y < tr[u].l)return 0;
if (x <= tr[u].l && tr[u].r <= y)return tr[u].sum[k];
return query(ls, x, y, k) + query(rs, x, y, k);
}
int main() {
cin >> n >> m;
build(1, 1, n);
for (int i = 1;i <= m;i++) {
int q, l, r; cin >> q >> l >> r;
if (q == 1) change(1, l, 0), change(1, r, 1);
else cout << query(1, 1, r, 0) - query(1, 1, l - 1, 1) << '\n';
}
}