mxqz扫描线
查看原帖
mxqz扫描线
234783
conprour楼主2021/11/15 21:42

RT,本题离散化做法类似扫描线思想,为了防止单点(如[4,4])没有意义,改变了区间的对应方式。

我找了一份码风好的代码,但是里面有点细节不太清楚,想问问大神们。(问题注释在代码里)

#include <bits/stdc++.h>
 
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define CLR(x, y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 6e5 + 5;
const int mod = 1e9 + 7;
 
int sum[maxn << 2], n, q, lazy[maxn << 2];
int t[maxn];
 
void push_up(int rt) {
    sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
 
void push_down(int rt, int l, int r) {
    if (lazy[rt] != -1) {
        int mid = (l + r) / 2;
        sum[rt << 1] = lazy[rt] * (t[mid + 1] - t[l]);
        sum[rt << 1 | 1] = lazy[rt] * (t[r + 1] - t[mid + 1]);
        lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
        lazy[rt] = -1;
    }
}
 
void update(int l, int r, int rt, int L, int R, int c) {
    if (L <= l && R >= r) {
        sum[rt] = c * (t[r + 1] - t[l]);
        lazy[rt] = c;
        return;
    }
    push_down(rt, l, r);
    int mid = (l + r) / 2;
    if (L <= mid) update(lson, L, R, c);
    if (R > mid) update(rson, L, R, c);
    push_up(rt);
}
 
struct node {
    int l, r, op;
} e[maxn];
 
int main() {

    scanf("%d%d", &n, &q);
    CLR(lazy, -1);
    int cnt = 0;
    for (int i = 1; i <= q; i++) {
        scanf("%d%d%d", &e[i].l, &e[i].r, &e[i].op);
        t[++cnt] = e[i].l;
        t[++cnt] = e[i].r+1;// 为什么+1 
    }
    sort(t + 1, t + 1 + cnt);
    int len = unique(t + 1, t + 1 + cnt) - t - 1;
    for (int i = 1; i <= q; i++) {
        int left = lower_bound(t + 1, t + 1 + len, e[i].l) - t;
        int right = lower_bound(t + 1, t + 1 + len, e[i].r +1) - t - 1;//为什么多-1 
        if (e[i].op == 1) update(1, len, 1, left, right, 1);
        else update(1, len, 1, left, right, 0);
        printf("%d\n", n - sum[1]);
    }
    return 0;
}
 
2021/11/15 21:42
加载中...