思路:
- 按行、列分别进行区间合并
- 区间合并结果相加, 去重(行列相交减一个格子)
注意事项:
tuple<int, int, int>
会超时,需要用 pair<int, pair<int, int >>
或者自定义结构体(tuple
模板实例化、成员访问get<n>()
、sort
都比 pair
更耗时, tuple
要多几倍时间)
- 结果的数据范围需要
long long
Code
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
typedef pair<int, pair<int, int>> PIII;
typedef long long ll;
vector<PIII> segs_x; // 存储 x1==x2 的区间
vector<PIII> segs_y; // 存储 y1==y2 的区间
ll merge(vector<PIII> & segs) {
sort(segs.begin(), segs.end());
segs.erase(unique(segs.begin(), segs.end()),segs.end());
vector<PIII> mr;
int l=-2e9, r=-2e9, k=-2e9;
ll res=0;
for (auto& seg : segs) {
if (seg.first != k || seg.second.first > r) {
if (k != -2e9) mr.push_back({k, {l, r}}), res+=r-l+1;
k=seg.first, l=seg.second.first, r=seg.second.second;
} else r = max(r, seg.second.second);
}
if (k != -2e9) mr.push_back({k, {l, r}}), res+=r-l+1;
segs = mr;
return res;
}
int main(void) {
int n; cin>>n;
while (n--) {
int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if (x1==x2) segs_x.push_back({x1, {min(y1,y2),max(y1,y2)}});
else segs_y.push_back({y1, {min(x1, x2), max(x1, x2)}});
}
ll res=merge(segs_x) + merge(segs_y); // 区间合并
for (auto & seg_x : segs_x) { // 去重
for (auto & seg_y : segs_y) {
if (seg_x.first >= seg_y.second.first && seg_x.first <= seg_y.second.second
&& seg_y.first >= seg_x.second.first && seg_y.first <= seg_x.second.second)
--res;
}
}
printf("%lld", res);
return 0;
}