poj 1151 Atlantis 线段树扫描线
2016-09-19 13:20
295 查看
题目
题意:给出一些矩形,求面积的并。
解法:
扫描线,每个矩形对应两个竖直的线段,左边的线段标记为1代表添加,右边的线段标记为-1,代表减。现在从左往右扫描。计算每次从一个条直线段到另一条线段中间的面积(线段树维护的总长度*两线段横坐标之差)。需要离散化, 线段树中叶子结点维护的区间左右坐标之差为1(离散后),每个结点还要记录当前段的标记,如果是0,那么当前段len为0,否则当前段len=lson.len+rson.len。
#include<cstdio> #include<string> #include<cstring> #include<iostream> #include<cmath> #include<algorithm> #include<vector> #include<map> using namespace std; #define all(x) (x).begin(), (x).end() #define for0(a, n) for (int (a) = 0; (a) < (n); (a)++) #define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++) #define mes(a,x,s) memset(a,x,(s)*sizeof a[0]) #define mem(a,x) memset(a,x,sizeof a) typedef long long ll; typedef pair<int, int> pii; const int INF =0x3f3f3f3f; const int maxn=200 ; int n,nL; vector<double>ve; map<double ,int >mp; struct Line { double x,le,ri; int flag; Line(){} Line(double x,double le,double ri,int flag):x(x),le(le),ri(ri),flag(flag){} bool operator<(const Line c)const { return x<c.x; } }Li[maxn+10]; struct Node { int le,ri,flag; double L,R,len; int MID() { return (le+ri)>>1; } }; struct SegmentTree { Node a[4*maxn]; void build(int ind,int le,int ri) { a[ind].le=le,a[ind].ri=ri; a[ind].len=0,a[ind].flag=0; a[ind].L=ve[le],a[ind].R=ve[ri]; if(le+1<ri) { int mid=a[ind].MID(); build(2*ind,le,mid); build(2*ind+1,mid,ri); } } void update(int ind,int le,int ri,int flag) { if(a[ind].le+1== a[ind].ri) { a[ind].flag+=flag; if(!a[ind].flag) a[ind].len=0; else a[ind].len=a[ind].R-a[ind].L; } else { int mid= a[ind].MID(); if(le<mid) update(ind*2 ,le,ri,flag);//小于,不是小于等于 if(ri>mid) update(ind*2+1,le,ri,flag); a[ind].len=a[ind*2].len+a[ind*2+1].len; } } }sgt; int main() { std::ios::sync_with_stdio(false); double L,U,R,D; int kase=0; while(cin>>n&&n) { ve.clear();nL=0; for0(i,n) { cin>>L>>D>>R>>U; ve.push_back(U); ve.push_back(D); Li[nL++]=Line(L,D,U,1); Li[nL++]=Line(R,D,U,-1); } sort(all(ve)); ve.erase(unique(all(ve)),ve.end() ); mp.clear(); int siz=ve.size(); for0(i,siz) mp[ve[i]]=i; sgt.build(1,0,siz-1); double ans=0; sort(Li,Li+nL); for0(i,nL) { if(i) ans+= sgt.a[1].len*(Li[i].x-Li[i-1].x); sgt.update(1,mp[Li[i].le],mp[Li[i].ri],Li[i].flag ); // cout<<i<<" "<<ans<<endl; } printf("Test case #%d\n",++kase); printf("Total explored area: %.2f\n\n",ans); } return 0; }
相关文章推荐
- POJ 1151 Atlantis(线段树扫描线)
- 【POJ】1151 Atlantis(线段树+扫描线+离散化)
- POJ 1151 Atlantis(线段树+扫描线+坐标离散求矩形面积并)
- POJ 1151 Atlantis 线段树扫描线
- poj 1151 Atlantis (线段树+扫描线+离散化)
- POJ(1151)——Atlantis(线段树 扫描线)
- POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]
- POJ 1151 Atlantis (扫描线+线段树)
- poj_1151 Atlantis && poj_1177 Picture(线段树+扫描线+离散化)
- poj 1151 Atlantis 线段树扫描线+离散化
- poj - 1151 - Atlantis(离线化+扫描线+线段树)
- poj 1151 Atlantis(线段树 扫描线)
- POJ 1151 Atlantis 矩形面积求交/线段树扫描线
- poj 1151 Atlantis (线段树扫描线)
- [poj 1151] Atlantis:扫描线+线段树求面积并
- poj 1151 & hdu 1542 Atlantis(线段树,扫描线)
- POJ 1151 Atlantis 矩形切割 || 线段树 扫描线
- POJ 1151 Atlantis (线段树求矩形面积并)
- poj 1151 Atlantis(多矩形面积) + poj 1177Picture(多矩形周长) 线段树进阶
- POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并