該題有很多種做法,亂搞可以過,最好的方法應該是掃描線,本題是掃描線模板題
官網數據第一個錯了,所以83分就是滿分
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
#define mp(x,y) make_pair(x,y)
#define fir first
#define sec second
struct SEG {
int l, r, h, s;
SEG(){}
SEG(int _l, int _r, int _h, int _s){
l=_l; r=_r; h=_h; s=_s;
}
}seg[2*N];
int p[2*N], cnt=0;
bool cmp(SEG a, SEG b){//從下往上掃描
return a.h<b.h;
}
struct node{
int num, len;//num是線段的個數,-1代表兩個子節點個數不一致。
}tree[N<<2];
void build(int rt, int l, int r){
tree[rt].num=0;
tree[rt].len=0;
if(l==r) return;
int mid=(l+r)>>1;
build(rt<<1, l, mid);
build(rt<<1|1, mid+1, r);
}
void pushdown(int rt, int l, int r){
if(tree[rt].num!=-1){
tree[rt<<1].num=tree[rt<<1|1].num=tree[rt].num;
int mid=(l+r)>>1;
if(tree[rt].num){
tree[rt<<1].len=p[mid+1]-p[l];
tree[rt<<1|1].len=p[r+1]-p[mid+1];
}
else{
tree[rt<<1].len=tree[rt<<1|1].len=0;
}
}
}
void pushup(int rt){
if(tree[rt<<1].num==-1 || tree[rt<<1|1].num==-1 || tree[rt<<1].num!=tree[rt<<1|1].num)
tree[rt].num=-1;
else
tree[rt].num=tree[rt<<1].num;
tree[rt].len=tree[rt<<1].len+tree[rt<<1|1].len;
}
void upd(int rt, int l, int r, int L, int R, int s){
if(L<=l && r<=R && tree[rt].num!=-1){
tree[rt].num+=s;
if(tree[rt].num)
tree[rt].len=p[r+1]-p[l];
else tree[rt].len=0;
return;
}
pushdown(rt, l, r);
int mid=(l+r)>>1;
if(L<=mid)
upd(rt<<1, l, mid, L, R, s);
if(R>mid)
upd(rt<<1|1, mid+1, r, L, R, s);
pushup(rt);
}
int main(){
int n;
scanf("%d", &n);
for(int i=1; i<=n; i++){
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
if(x1>x2) swap(x1, x2);
if(y1>y2) swap(y1, y2);
seg[++cnt]=SEG(x1,x2,y1,1);
p[cnt]=x1;
seg[++cnt]=SEG(x1,x2,y2,-1);
p[cnt]=x2;
}
sort(p+1, p+1+cnt);
sort(seg+1, seg+1+cnt, cmp);
int m=unique(p+1, p+1+cnt)-p-1;
build(1, 1, m);
int ans=0, pre=0;
for(int i=1; i<=cnt; i++){
ans+=(seg[i].h-pre)*tree[1].len;
pre=seg[i].h;
int l=lower_bound(p+1, p+1+m, seg[i].l)-p;
int r=lower_bound(p+1, p+1+m, seg[i].r)-p;
if(l<r)
upd(1, 1, m, l, r-1, seg[i].s); //這個地方用r-1的原因是
//如果要算p[3]-p[1]的長度,會被分成p[2]-p[1] + p[3]-p[3] 這樣的話p[3]-p[2]是沒有被
算上的,所以我們統一用p[r+1]-p[l],使區間連續起來。所以初始化的時候就需要r-1操作
}
printf("%d\n", ans);
return 0;
}