蓝桥 第八届 A组 油漆面积

该题有很多种做法,乱搞可以过,最好的方法应该是扫描线,本题是扫描线模板题

官网数据第一个错了,所以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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章