hdu 1542/1255 Atlantis/覆蓋的面積
阿新 • • 發佈:2019-01-13
兩道掃描線+線段樹的入門題。
基本沒有什麼區別,前者是模板,後者因為是求覆蓋次數至少在兩次以上的,這個同樣是具有並集性質的,所以把cover的判斷條件更改一下就可以了qwq。
hdu1542 程式碼如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define MAXN 200010 using namespace std; int n,c,cnt; double y[MAXN]; struct Node{ double x,l,r; int cover; bool flag; }node[MAXN]; struct Line { double x,y_up,y_down; int flag; }line[MAXN]; inline bool cmp(struct Line x,struct Line y){return x.x<y.x;} inline int ls(int x){return x<<1;} inline int rs(int x){return x<<1|1;} inline void build(int x,int l,int r) { node[x].l=y[l],node[x].r=y[r],node[x].x=-1,node[x].flag=false,node[x].cover=0; if(l+1==r){node[x].flag=true; return;} int mid=(l+r)>>1; build(ls(x),l,mid); build(rs(x),mid,r); } inline double q_update(int x,double pos,double l,double r,int flag) { if(l>=node[x].r||r<=node[x].l) return 0; if(node[x].flag) { if(node[x].cover<=0) { node[x].x=pos; node[x].cover+=flag; return 0; } double pre=node[x].x; double ans=(pos-pre)*(node[x].r-node[x].l); node[x].x=pos; node[x].cover+=flag; return ans; } return q_update(ls(x),pos,l,r,flag)+q_update(rs(x),pos,l,r,flag); } int main() { scanf("%d",&n); while(n!=0) { double x1,x2,y1,y2; cnt=0; for(int i=1;i<=n;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); line[++cnt].x=x1,line[cnt].y_down=y1,line[cnt].y_up=y2,line[cnt].flag=1,y[cnt]=y1; line[++cnt].x=x2,line[cnt].y_down=y1,line[cnt].y_up=y2,line[cnt].flag=-1,y[cnt]=y2; } sort(&line[1],&line[cnt+1],cmp); sort(&y[1],&y[cnt+1]); build(1,1,cnt); double ans=0; for(int i=1;i<=cnt;i++) ans+=q_update(1,line[i].x,line[i].y_down,line[i].y_up,line[i].flag); printf("Test case #%d\nTotal explored area: %.2lf\n\n",++c,ans); scanf("%d",&n); } return 0; }
hdu1255 程式碼如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define MAXN 200010 using namespace std; int n,c,cnt,t; double y[MAXN]; struct Node{ double x,l,r; int cover; bool flag; }node[MAXN]; struct Line { double x,y_up,y_down; int flag; }line[MAXN]; inline bool cmp(struct Line x,struct Line y){return x.x<y.x;} inline int ls(int x){return x<<1;} inline int rs(int x){return x<<1|1;} inline void build(int x,int l,int r) { node[x].l=y[l],node[x].r=y[r],node[x].x=-1,node[x].flag=false,node[x].cover=0; if(l+1==r){node[x].flag=true; return;} int mid=(l+r)>>1; build(ls(x),l,mid); build(rs(x),mid,r); } inline double q_update(int x,double pos,double l,double r,int flag) { if(l>=node[x].r||r<=node[x].l) return 0; if(node[x].flag) { if(node[x].cover<=1) { node[x].x=pos; node[x].cover+=flag; return 0; } double pre=node[x].x; double ans=(pos-pre)*(node[x].r-node[x].l); node[x].x=pos; node[x].cover+=flag; return ans; } return q_update(ls(x),pos,l,r,flag)+q_update(rs(x),pos,l,r,flag); } int main() { scanf("%d",&t); while(t--) { scanf("%d",&n); double x1,x2,y1,y2; cnt=0; for(int i=1;i<=n;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); line[++cnt].x=x1,line[cnt].y_down=y1,line[cnt].y_up=y2,line[cnt].flag=1,y[cnt]=y1; line[++cnt].x=x2,line[cnt].y_down=y1,line[cnt].y_up=y2,line[cnt].flag=-1,y[cnt]=y2; } sort(&line[1],&line[cnt+1],cmp); sort(&y[1],&y[cnt+1]); build(1,1,cnt); double ans=0; for(int i=1;i<=cnt;i++) ans+=q_update(1,line[i].x,line[i].y_down,line[i].y_up,line[i].flag); printf("%.2lf\n",ans); } return 0; }