RE爆零求助
查看原帖
RE爆零求助
532209
pstdjr楼主2023/6/29 22:53

代码:

//扫描线经典题目
//洛谷 P5490 【模板】扫描线  HDU 1542 Mars Map
//https://www.luogu.com.cn/problem/P5490
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int maxn=105;

struct edge{
	int l, r, h;
	int f;   //1为下边界,-1为上边界
}ss[maxn*2];

bool cmp(edge x, edge y){
	return x.h < y.h;
}

int n, m;

int pos[maxn*2];

struct tree{
	int l, r, cnt;  //cnt:覆盖了多少次
	int len;  //被覆盖了多长
}t[maxn*4];

void build(int p, int l, int r){
	t[p].l = l;
	
	t[p].r = r;
	
	t[p].cnt = 0;
	
	t[p].len = 0;
	
	if (l == r)
		return;
	
	int mid=(l+r)/2;
	
	build(p*2, l, mid);
	
	build(p*2+1, mid+1, r);
}

void pushup(int p){
	if (t[p].cnt)
		t[p].len = pos[t[p].r+1] - pos[t[p].l];
	else if (t[p].l == t[p].r)
		t[p].len = 0;
	else
		t[p].len = t[p*2].len + t[p*2+1].len;
}

void update(int p, int l, int r, int val){
	if (l <= t[p].l && r >= t[p].r){
		t[p].cnt += val;
		pushup(p);
		return;
	}
	
	int mid=(t[p].l+t[p].r)/2;
	
	if (l <= mid)
		update(p*2, l, r, val);
	
	if (r > mid)
		update(p*2+1, l, r, val);
	
	pushup(p);
}

int binary(int k){
	int l=1, r=m;
	
	while (l < r){
		int mid=(l+r)/2;
		
		if (pos[mid] >= k)
			r = mid;
		else
			l = mid + 1;
	}
	
	return l;
}

signed main(){
	cin >> n;
	
	int num=1;
	
	for (int i=1; i<=n; i++){
		int x1, y1, x2, y2;
		
		cin >> x1 >> y1 >> x2 >> y2;
		
		ss[num].l = x1;
		
		ss[num].r = x2;
		
		ss[num].h = y1;
		
		ss[num].f = 1;
		
		ss[num+1].l = x1;
		
		ss[num+1].r = x2;
		
		ss[num+1].h = y2;
		
		ss[num+1].f = -1;
		
		pos[num] = x1;
		
		pos[num+1] = x2;
		
		num += 2;
	}
	
	num--;
	
	sort(ss+1, ss+num+1, cmp);
	
	sort(pos+1, pos+num+1);
	
	m = 0;
	
	pos[0] = -1;
	
	for (int i=1; i<=num; i++)
		if (pos[i] != pos[i-1])
			pos[++m] = pos[i];  //去重
	
	build(1, 1, m);
	
	int ans=0;
	
	for (int i=1; i<num; i++){
		int l=binary(ss[i].l);
		
		int r=binary(ss[i].r)-1;  //离散化
		
		update(1, l, r, ss[i].f);
		
		ans += (ss[i+1].h - ss[i].h) * t[1].len;
	}
	
	cout << ans << '\n';
	
	return 0;
}
2023/6/29 22:53
加载中...