hdu1542 Atlantis (线段树+矩阵面积并+离散化)
InputThe input file consists of several test cases. Each test case starts with a line containing a single integer n (1<=n<=100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2 (0<=x1<x2<=100000;0<=y1<y2<=100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area.
The input file is terminated by a line containing a single 0. Don’t process it.OutputFor each test case, your program should output one section. The first line of each section must be “Test case #k”, where k is the number of the test case (starting with 1). The second one must be “Total explored area: a”, where a is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point.
Output a blank line after each test case.
Sample Input
2 10 10 20 20 15 15 25 25.5 0
Sample Output
Test case #1 Total explored area: 180.00
思路:
扫描线+矩阵面积并,被离散化难到了,之前一直没想到离散化要弄成一个左开右闭的区间
实现代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mid int m = (l + r) >> 1 const int M = 1e5+10; struct seg{ double l,r,h; int s; seg(){} seg(double a,double b,double c,int d):l(a),r(b),h(c),s(d){} bool operator < (const seg &cmp) const { return h < cmp.h; } }t[M]; double sum[M<<2],x[M<<2]; int cnt[M<<2]; void pushup(int l,int r,int rt){ if(cnt[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 l,int r,int rt){ if(L <= l&&R >= r){ cnt[rt] += c; pushup(l,r,rt); return ; } mid; if(L <= m) update(L,R,c,lson); if(R > m) update(L,R,c,rson); pushup(l,r,rt); } int bin(double key,int n,double x[]){ int l = 0;int r = n-1; while(l <= r){ mid; if(x[m] == key) return m; else if(x[m] < key) l = m+1; else r = m-1; } return -1; } int main() { int n,cas = 1; double a,b,c,d; while(~scanf("%d",&n)&&n){ int m = 0; while(n--){ cin>>a>>b>>c>>d; x[m] = a; t[m++] = seg(a,c,b,1); x[m] = c; t[m++] = seg(a,c,d,-1); } sort(x,x+m); sort(t,t+m); int nn = 1; for(int i = 1;i < m;i++){ if(x[i]!=x[i-1]) x[nn++] = x[i]; } //for(int i = 0;i < nn;i ++) // cout<<x[i]<<" "; //cout<<endl; double ret = 0; for(int i = 0;i < m-1;i ++){ int l = bin(t[i].l,nn,x); int r = bin(t[i].r,nn,x)-1; //cout<<t[i].l<<" "<<t[i].r<<endl; //cout<<"l: "<<l<<" r: "<<r<<endl; if(l <= r) update(l,r,t[i].s,0,nn-1,1); //cout<<sum[1]<<endl; ret += sum[1] * (t[i+1].h - t[i].h); } printf("Test case #%d\nTotal explored area: %.2lf\n\n",cas++ , ret); memset(cnt,0,sizeof(cnt)); memset(sum,0,sizeof(sum)); } return 0; }