标签:close file write sum nbsp 树节点 view ase first
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 21734 | Accepted: 8179 |
Description
Input
Output
Sample Input
2 10 10 20 20 15 15 25 25.5 0
Sample Output
Test case #1 Total explored area: 180.00
Source
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> using namespace std; const int N=205; #define m (l+r)/2 #define lson o<<1,l,m #define rson o<<1|1,m+1,r #define lc o<<1 #define rc o<<1|1 inline int read(){ char c=getchar();int x=0,f=1; while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} return x*f; } int n,cnt=0; double x1,y1,x2,y2,mp[N]; struct seg{ double l,r,h; int f;//1 or -1 seg(double a=0,double b=0,double c=0,int d=0):l(a),r(b),h(c),f(d){} bool operator <(const seg &r)const{return h<r.h;} }a[N]; struct node{ double sum; int cov; }t[N<<2]; inline int Bin(double v){ int l=1,r=cnt; while(l<=r){ int mid=(l+r)>>1; if(mp[mid]==v) return mid; else if(v<mp[mid]) r=mid-1; else l=mid+1; } return -1; } inline void pushUp(int o,int l,int r){ if(t[o].cov) t[o].sum=mp[r+1]-mp[l]; else if(l==r) t[o].sum=0; else t[o].sum=t[lc].sum+t[rc].sum; } void update(int o,int l,int r,int ql,int qr,int v){ if(ql<=l&&r<=qr){ t[o].cov+=v; pushUp(o,l,r); }else{ if(ql<=m) update(lson,ql,qr,v); if(m<qr) update(rson,ql,qr,v); pushUp(o,l,r); } } int cas=0; int main(int argc, const char * argv[]) { while((n=read())){ double ans=0; for(int i=1;i<=n;i++){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); a[i*2-1]=seg(x1,x2,y1,1); a[i*2]=seg(x1,x2,y2,-1); mp[2*i-1]=x1; mp[2*i]=x2; } sort(mp+1,mp+1+2*n); sort(a+1,a+1+2*n); cnt=0;mp[++cnt]=mp[1]; for(int i=2;i<=2*n;i++) if(mp[i]!=mp[i-1]) mp[++cnt]=mp[i]; memset(t,0,sizeof(t)); for(int i=1;i<=2*n-1;i++){//最后一个不用 int ql=Bin(a[i].l),qr=Bin(a[i].r)-1; if(ql<=qr) update(1,1,cnt,ql,qr,a[i].f); ans+=t[1].sum*(a[i+1].h-a[i].h); } printf("Test case #%d\n",++cas); printf("Total explored area: %.2f\n\n",ans); } return 0; }
线段树需要插入线段,删除线段,求线段覆盖的总长度,貌似还是用标记永久化比较方便,否则删(我)除(没)很(写)麻(出)烦(来)
注意这个线段树节点是一段区间哦
离散化m忘清0了 WA了几次
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> using namespace std; const int N=205; #define lson x<<1,l,mid #define rson x<<1|1,mid+1,r #define lc x<<1 #define rc x<<1|1 inline int read(){ char c=getchar();int x=0,f=1; while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} return x*f; } int n; double x1,y1,x2,y2; struct Seg{ double l,r,y; int f; Seg(double l=0,double r=0,double y=0,int f=0):l(l),r(r),y(y),f(f){} bool operator <(const Seg &a)const{return y<a.y;} }a[N]; double mp[N];int m; void iniMP(){ sort(mp+1,mp+1+m); int p=0; mp[++p]=mp[1]; for(int i=2;i<=m;i++) if(mp[i]!=mp[i-1]) mp[++p]=mp[i]; m=p; } inline int Bin(double v){ int l=1,r=m; while(l<=r){ int mid=(l+r)>>1; if(v==mp[mid]) return mid; else if(v<mp[mid]) r=mid-1; else l=mid+1; } return 0; } struct node{ double sum; int cov; node():sum(0),cov(0){} }t[N<<2]; void pushUp(int x,int l,int r){ if(t[x].cov) t[x].sum=mp[r+1]-mp[l]; else if(l==r) t[x].sum=0; else t[x].sum=t[lc].sum+t[rc].sum; } void segCov(int x,int l,int r,int ql,int qr,int v){ if(ql<=l&&r<=qr) t[x].cov+=v,pushUp(x,l,r); else{ int mid=(l+r)>>1; if(ql<=mid) segCov(lson,ql,qr,v); if(mid<qr) segCov(rson,ql,qr,v); pushUp(x,l,r); } } int cas=0; int main(int argc, const char * argv[]) { while((n=read())){ m=0; for(int i=1;i<=n;i++){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); a[i*2-1]=Seg(x1,x2,y1,1); a[i*2]=Seg(x1,x2,y2,-1); mp[++m]=x1;mp[++m]=x2; } iniMP(); n<<=1; sort(a+1,a+1+n); memset(t,0,sizeof(t)); double ans=0; for(int i=1;i<=n-1;i++){ int ql=Bin(a[i].l),qr=Bin(a[i].r)-1; if(ql<=qr) segCov(1,1,m,ql,qr,a[i].f); ans+=t[1].sum*(a[i+1].y-a[i].y); } printf("Test case #%d\n",++cas); printf("Total explored area: %.2f\n\n",ans); } return 0; }
POJ1151Atlantis 矩形面积并[线段树 离散化 扫描线]
标签:close file write sum nbsp 树节点 view ase first
原文地址:http://www.cnblogs.com/candy99/p/5958587.html