请求添加题解
查看原帖
请求添加题解
1227383
MPLN楼主2025/2/6 17:51

我的题解

个人认为和其他题解思路不太一样。直接维护了线段,没有用优先队列等数据结构。题解里面有详细讲解,面向新手和扫描线初学者。且代码很简单。

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) x & -x
int n, b[100010], ans = 0, tx, ty;
char op;
struct node { // 存点
    int x, y, f, e; // f存储此点是否是竖线段起点,e为是否是终点
    bool operator<(const node& b) const {
        if (op == 'x') return x != b.x ? x < b.x : y < b.y;
        else return y != b.y ? y < b.y : x < b.x;
    }
} a[100010];
int t[100010];
// 树状数组模版
void add(int x, int k) { for (; x <= n; x += lowbit(x)) t[x] += k; }
int ask(int x) { int sum = 0; for (; x; x -= lowbit(x)) sum += t[x]; return sum; }
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> tx >> ty;
        a[i] = {tx, ty, 0, 0}, b[i] = tx;
    }
    sort(b + 1, b + n + 1); // x离散化
    for (int i = 1; i <= n; i++) a[i].x = lower_bound(b + 1, b + n + 1, a[i].x) - b;
    op = 'x', sort(a + 1, a + n + 1); // 按x排序来统计竖线
    for (int i = 2; i <= n; i++)
        if (a[i].x == a[i - 1].x) // 相同x构成竖线
            a[i - 1].f = a[i].e = 1; // 分别是竖线段首尾
    op = 'y', sort(a + 1, a + n + 1); // 按y排序来找横线
    for (int i = 1; i <= n; i++) {
        if (a[i].e) add(a[i].x, -1); // 线段结束
        if (i > 1 && a[i].y == a[i - 1].y) // 两点构成横线
            ans += ask(a[i].x - 1) - ask(a[i - 1].x); // 查询中间竖线段数量=交点
        if (a[i].f) add(a[i].x, 1); // 新线段加入
    }
    cout << ans + n; // 别忘了原来的黑点!
    return 0;
}
2025/2/6 17:51
加载中...