Atlantis HDU - 1542 (掃描線 + 線段樹)
阿新 • • 發佈:2019-01-01
https://cn.vjudge.net/problem/HDU-1542
題意
求矩形覆蓋的面積
思路
模板題
#include <bits/stdc++.h> using namespace std; const int maxn = 210; int n,cnt,num,p; double ls[maxn*2],ans; struct edg ///邊 { double l,r,h; int flag; ///1為下線 -1為上線 bool operator < (const edg &b)const{ return h < b.h; } }edge[maxn]; struct node ///線段樹 { int l,r,lazy; double len; }tree[maxn*4]; void add(double x1,double x2,double h,int f) { edge[cnt].l = x1; edge[cnt].r = x2; edge[cnt].h = h; edge[cnt++].flag = f; } void build(int rt,int l,int r) { tree[rt].l = l; tree[rt].r = r; tree[rt].len = 0; tree[rt].lazy = 0; if(l == r) return ; int mid = (l+r)>>1; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); } void pushup(int rt) { if(tree[rt].lazy) /// 存在 { tree[rt].len = ls[tree[rt].r+1] - ls[tree[rt].l]; } else if(tree[rt].l == tree[rt].r) ///最小距離 為0 { tree[rt].len = 0; } else tree[rt].len = tree[rt<<1].len + tree[rt<<1|1].len; ///不存在整段 但可能存在部分 } void updata(int rt,int l,int r,int val) { if(tree[rt].l == l&&tree[rt].r == r) { tree[rt].lazy += val;///新增或者去掉 pushup(rt); return ; } int mid = (tree[rt].l + tree[rt].r)>>1; if(l > mid) updata(rt<<1|1,l,r,val); else if(mid >= r) updata(rt<<1,l,r,val); else { updata(rt<<1,l,mid,val); updata(rt<<1|1,mid+1,r,val); } pushup(rt); } int main() { int i,j,k; int ca = 1; while(scanf("%d",&n) != EOF&&n) { ans = cnt = p = 0; for(i=1;i<=n;i++) { double x1,x2,y1,y2; scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); add(x1,x2,y1,1); add(x1,x2,y2,-1); ls[p++] = x1; ls[p++] = x2; } sort(edge,edge+cnt); ///從下向上掃描 sort(ls,ls+p); int m = unique(ls,ls+p) - ls; ///去重 m為驅蟲後元素個數 build(1,0,m-1); for(i=0;i<cnt-1;i++) { int l = lower_bound(ls,ls+m,edge[i].l) - ls; ///找到對應的位置 int r = lower_bound(ls,ls+m,edge[i].r) - ls; updata(1,l,r-1,edge[i].flag); ///修改 ans += (edge[i+1].h - edge[i].h) * tree[1].len;///只有有高度差才會改變 } printf("Test case #%d\n",ca++); printf("Total explored area: %.2f\n\n",ans); } return 0; }