P8463 「REOI-1」深潜的第六兽 题解
思路
由于兽是从上往下落的,可以考虑根据 \(h_i\) 的大小从大到小进行排序,遍历到第 \(i\) 座空岛时,查询区间 \(\left[l_i,r_i\right]\) 中兽的数量,之后把区间 \(\left[l_i,r_i\right]\) 清零,然后分别在 \(l_i\) 和 \(r_i\) 上加上区间 \(\left[l_i,r_i\right]\) 中兽的数量即可。可以用线段树或其他你喜欢的数据结构来维护。
由于空岛之间没有重叠部分,所以每次更新操作都不会影响同一高度的空岛,只会影响到下面的空岛。
最终输出兽的总数量即可。
时间复杂度 $ \mathcal O (m\log{R})$,其中 \(R=\max{r_i}\)。
代码
#include <bits/stdc++.h>
#define int long long
#define ls x<<1
#define rs x<<1|1
using namespace std;
struct node {
int l, r, h;
} land[500010];
int n, m, w[100010];
int sum[100010 << 2], tag[100010 << 2];
const int mod = 998244353;
bool cmp(node a, node b) {
return a.h > b.h;
}
void bulid(int x, int l, int r) {
if (l == r) {
sum[x] = w[l];
sum[x] %= mod;
return;
}
int mid = l + r >> 1;
bulid(ls, l, mid);
bulid(rs, mid + 1, r);
sum[x] = sum[ls] + sum[rs];
sum[x] %= mod;
}
void pushdown(int x) {
tag[ls] = tag[rs] = tag[x];
sum[ls] = sum[rs] = 0;
tag[x] = 0;
}
void update(int x, int L, int R, int l, int r) {
if (l >= L && r <= R) {
tag[x] = 1;
sum[x] = 0;
return;
}
if (tag[x]) {
pushdown(x);
}
int mid = l + r >> 1;
if (L <= mid) {
update(ls, L, R, l, mid);
}
if (R > mid) {
update(rs, L, R, mid + 1, r);
}
sum[x] = sum[ls] + sum[rs];
sum[x] %= mod;
}
void add(int x, int st, int l, int r, int data) {
if (l == r && l == st) {
sum[x] += data;
sum[x] %= mod;
return;
}
int mid = l + r >> 1;
if (tag[x]) {
pushdown(x);
}
if (st <= mid) {
add(ls, st, l, mid, data);
}
if (st > mid) {
add(rs, st, mid + 1, r, data);
}
sum[x] = sum[ls] + sum[rs];
sum[x] %= mod;
}
int query(int x, int L, int R, int l, int r) {
if (l >= L && r <= R) {
return sum[x];
}
if (tag[x]) {
pushdown(x);
}
int mid = l + r >> 1, res = 0;
if (L <= mid) {
res += query(ls, L, R, l, mid);
}
if (R > mid) {
res += query(rs, L, R, mid + 1, r);
}
return res;
}
signed main() {
scanf("%lld%lld", &n, &m);
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &land[i].l, &land[i].r, &land[i].h);
}
for (int i = 1; i <= n; i++) {
int x;
scanf("%lld", &x);
w[x]++;
}
sort(land + 1, land + 1 + m, cmp);
bulid(1, 1, (int)1e5);
for (int i = 1; i <= m; i++) {
int l = land[i].l, r = land[i].r;
int tmp = query(1, l, r, 1, (int)1e5);
//printf("%d%d%d\n", l, r, tmp);
update(1, l, r, 1, (int)1e5);
add(1, l, 1, (int)1e5, tmp);
add(1, r, 1, (int)1e5, tmp);
}
printf("%lld", sum[1]%mod);
return 0;
}

浙公网安备 33010602011771号