题目
https://codeforces.com/gym/103260/problem/H
思路
写了一坨答辩代码,已经神志不清了,后面再补上思路吧,先给上题解的描述还有草稿纸上一些图。
简而言之,学会了一种套路,求一些线段中选出不被任何一个线段完全覆盖的所有线段,支持删除线段操作。
代码
#include <bits/stdc++.h>
using namespace std;
#define MAXN 500005
int n, q;
int a[MAXN];
pair<pair<int, int>, int> Q[MAXN];
#define LX (x<<1)
#define RX ((x<<1)|1)
struct segment_tree {
struct node {
int l, r;
int v; // 区间最大值
int num; // 区间线段个数
int tag; // 区间加标记
} a[MAXN*8];
void merge(int x) {
if (a[x].l == a[x].r) return;
a[x].num = a[LX].num + a[RX].num;
a[x].v = max(a[LX].v, a[RX].v);
}
void build(int x, int l, int r) {
a[x].l = l;
a[x].r = r;
a[x].num = a[x].tag = 0;
a[x].v = -1;
if (l == r) return;
build(LX, l, (l+r)/2);
build(RX, (l+r)/2+1, r);
merge(x);
}
void down_tag(int x) {
if (a[x].l == a[x].r) return;
if (a[LX].num) a[LX].v += a[x].tag, a[LX].tag += a[x].tag;
if (a[RX].num) a[RX].v += a[x].tag, a[RX].tag += a[x].tag;
a[x].tag = 0;
}
void set(int x, int pos, int v) {
// 将线段 pos 处的值设置为 v,若 v==-1 则说明清除这个点
if (a[x].l == a[x].r) {
a[x].v = v;
a[x].num = (v>=0);
return;
}
down_tag(x);