一道对我来说真正意义的难题 我卡卡我卡卡大佬不要蕨 小白选手
从0学了离散化和线段树 终于写出来了 非常有成就感
#include<bits/stdc++.h>
using namespace std;
int c, n;
set<int> s;
set<int> colors;
vector<int> v;
map<int, int> m;
int L[10002], R[10002];
int Count = 0;
int res = 0;
struct node {
int l, r;
int value;
int lazy = 0;
} tree[80005];
void build_tree(int l, int r, int u) {
tree[u].l = l;
tree[u].r = r;
tree[u].value = 0;
if (l == r)
return;
build_tree(l, (l + r) >> 1, u << 1);
build_tree(((l + r) >> 1) + 1, r, (u << 1) + 1);
}
void pushup(int u) {
if (tree[u << 1].value == tree[(u << 1) + 1].value) {
tree[u].value = tree[u << 1].value;
}
else {
tree[u].value = 0; // 颜色不确定
}
}
void pushdown(int u) {
if (tree[u].lazy != 0) {
tree[u << 1].value = tree[u].value;
tree[(u << 1) + 1].value = tree[u].value;
tree[u << 1].lazy = tree[u].lazy;
tree[(u << 1) + 1].lazy = tree[u].lazy;
tree[u].lazy = 0;
}
}
void Color(int l, int r, int color, int u = 1) {
if (l <= tree[u].l && r >= tree[u].r) {
tree[u].value = color;
tree[u].lazy = color;
return;
}
if (tree[u].value != 0)
pushdown(u);
int mid = (tree[u].l + tree[u].r) >> 1;
if (l <= mid) Color(l, r, color, u << 1);
if (r > mid) Color(l, r, color, (u << 1) + 1);
pushup(u);
}
void dfs(int u = 1) {
if (tree[u].value != 0)
colors.insert(tree[u].value);
if (tree[u].l == tree[u].r)
return;
dfs(u << 1);
dfs((u << 1) + 1);
}
void clear(int u = 1) {
if (tree[u].l == tree[u].r) {
tree[u].value = 0;
tree[u].lazy = 0;
return;
}
tree[u].value = 0;
tree[u].lazy = 0;
clear(u << 1);
clear((u << 1) + 1);
}
int main() {
cin >> c;
while (c--) {
cin >> n;
s.clear();
m.clear();
v.clear();
colors.clear();
Count = 0;
res = 0;
clear();
while (n--) {
int l, r;
cin >> l >> r;
s.insert(l);
s.insert(r);
L[Count] = l;
R[Count++] = r;
}
for (int num : s)
v.push_back(num);
sort(v.begin(), v.end());
int pre = v[0];
for (int i = 1; i < v.size(); i++) {
if (v[i] - pre > 1) {
v.insert(v.begin() + i, pre + 1);
i++;
}
pre = v[i];
}
build_tree(1, v.size(), 1);
for (int i = 0; i < Count; i++) {
Color(distance(v.begin(), find(v.begin(), v.end(), L[i])) + 1,
distance(v.begin(), find(v.begin(), v.end(), R[i])) + 1, i + 1);
}
dfs();
cout << colors.size() << endl;
}
return 0;
}
离散化想了一会 用了一些没用过的api:
distance(v.begin(), find(v.begin(), v.end(), L[i])
distance代表迭代器之间的距离 求下标非常好用
find()返回迭代器对象
然后就是套用线段树模板 稍微更改一下pushup pushdown update和query就可以啦