Atlantis HDU - 1542 掃描線 矩陣面積並

題意:求矩陣面積並(注意座標是浮點)

題解:因爲座標是浮點,所以需要離散化。然後重點在於離散化之後的工作,即把每條矩形看成兩條線段,從下往上掃描。每次掃到矩形的下邊就把區間+1,上邊爲區間-1,然後每次的面積就是非零區間的長度*兩條掃描線之間的高度,加起來就可以

區間修改要用到線段樹優化

具體圖片流程可以看這裏

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mem(s) memset(s, 0, sizeof(s))
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
const int maxn = 2000+5;
const int mod = 998244353;
struct edge {
	double l,r,h;
	int f;
	edge(){}
	edge(double tl,double tr,double th,int tf){
		l=tl;r=tr;h=th;f=tf;
	}
	bool operator <(const edge &rhs)const {
		return h<rhs.h;
	}
}a[maxn];
double X[maxn],sum[maxn<<2];int tag[maxn<<2];
void init(){
	memset(sum,0,sizeof(sum));
	memset(tag,0,sizeof(tag));
}
void push_up(int rt,int l,int r){
	if(tag[rt])sum[rt]=X[r+1]-X[l];
	else if(l==r)sum[rt]=0;
	else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int L,int R,int c,int rt,int l,int r){
	if(L<=l&&r<=R){
		tag[rt]+=c;
		push_up(rt,l,r);
		return ;
	}
	int mid=(l+r)>>1;
	if(L<=mid)update(L,R,c,rt<<1,l,mid);
	if(R>mid)update(L,R,c,rt<<1|1,mid+1,r);
	push_up(rt,l,r);
}
int main() 
{
	int n,kase=0;
	while(scanf("%d",&n)!=EOF&&n){
		int cnt=0;
		for(int i=0;i<n;i++){
			double xa,ya,xb,yb;
			scanf("%lf%lf%lf%lf",&xa,&ya,&xb,&yb);
			a[++cnt]=edge(xa,xb,yb,1);
			X[cnt]=xa;
			a[++cnt]=edge(xa,xb,ya,-1);
			X[cnt]=xb;
		}
		sort(X+1,X+cnt+1);
		sort(a+1,a+cnt+1);
		int m=unique(X+1,X+cnt+1)-X-1;
		init();
		double ans=0;
		for(int i=1;i<=cnt-1;i++){
			int l=lower_bound(X+1,X+m+1,a[i].l)-X;
			int r=lower_bound(X+1,X+m+1,a[i].r)-X;
			update(l,r-1,1.0*a[i].f,1,1,m);
			ans+=sum[1]*(a[i+1].h-a[i].h);
			//cout<<ans<<endl;
		}
		printf("Test case #%d\nTotal explored area: ",++kase);
		printf("%.2f\n",ans);
		printf("\n");

	}
	return 0;
}

 

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