Atlantis
题意:求矩形的面积并
解法:
扫描线+线段树维护+离散化
扫描矩形左右边界,左边为入边,右边为出边,使用线段树维护段中的覆盖长度即可
离散化y坐标,进行线段树的左右边界维护
不同于传统的建树,左树为 [l,mid],右树为[mid,r];//为了相减方便**
//比如 [1,2][2,4],这样的建立方式,当插入[1,4]时,得出的len值为1+2,但是传统的建图[1,2][3,4]得到的len=2
可以参考这个博文对于扫描线的分析yuzhou627
[poj1151.cpp]
- #include<iostream>
- #include<cstring>
- #include <algorithm>
- #include<cstdlib>
- #include<vector>
- #include<cmath>
- #include<stdlib.h>
- #include<iomanip>
- #include<list>
- #include<deque>
- #include<map>
- #include <stdio.h>
- #include <queue>
- #define maxn 5000+5
- #define inf 0x3f3f3f3f
- #define INF 0x3FFFFFFFFFFFFFFFLL
- #define rep(i,n) for(i=0;i<n;i++)
- #define reP(i,n) for(i=1;i<=n;i++)
- #define ull unsigned long long
- #define ll long long
- #define LL(x) x<<1
- #define RR(x) x<<1|1
- #define cle(a) memset(a,0,sizeof(a))
- using namespace std;
- struct Line{//扫描线
- double x,upy,downy;
- int flag;
- Line(double a,double b,double c,int d) : x(a), upy(b), downy(c), flag(d){}
- Line(){}
- }line[maxn];
- struct node{
- int l,r,flag;
- double ly,ry,len;
- int Mid(){
- return (l+r)>>1;
- }
- }tree[maxn<<2];
- double hash[maxn];
- bool cmp(Line a,Line b){return a.x<b.x;
- }
- void build(int rt,int l,int r){
- tree[rt].l=l,tree[rt].r=r;
- tree[rt].ly=hash[l],tree[rt].ry=hash[r];
- tree[rt].flag=0,tree[rt].len=0;
- if(tree[rt].l+1==tree[rt].r)return;
- int mid=(l+r)>>1;
- build(LL(rt),l,mid),build(RR(rt),mid,r);//右边为mid并非mid+1,
- }
- void doit(int x){//更新覆盖段
- if(tree[x].flag)tree[x].len=tree[x].ry-tree[x].ly;
- else if(tree[x].l+1==tree[x].r)tree[x].len=0;
- else tree[x].len=tree[RR(x)].len+tree[LL(x)].len;
- }
- void update(int rt,Line a){//更新
- if(a.upy==tree[rt].ly&&a.downy==tree[rt].ry){
- tree[rt].flag+=a.flag;
- doit(rt);return;
- }
- if(a.downy<=tree[LL(rt)].ry)update(LL(rt),a);
- else if(a.upy>=tree[RR(rt)].ly)update(RR(rt),a);
- else{
- Line temp=a;temp.downy=tree[LL(rt)].ry;
- update(LL(rt),temp);
- temp=a;temp.upy=tree[RR(rt)].ly;
- update(RR(rt),temp);
- }
- doit(rt);
- return;
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("in.txt","r",stdin);
- //freopen("out.txt","w",stdout);
- #endif
- int n;
- int T=1;
- while(cin>>n&&n){
- int i;
- for(i=1;i<=n;i++){
- double a,b,c,d;scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
- line[2*i-1]=Line(a,b,d,1);line[2*i]=Line(c,b,d,-1);
- hash[2*i-1]=b,hash[2*i]=d;
- }
- sort(line,line+2*n+1,cmp);sort(hash,hash+1+n*2);
- int m=2*n;
- build(1,1,m);update(1,line[1]);
- double ans=0.0;
- for(i=2;i<=m;i++){
- ans+=(tree[1].len)*(line[i].x-line[i-1].x);
- update(1,line[i]);
- }
- printf("Test case #%d\nTotal explored area: %.2f\n\n",T++,ans);
- }
- return 0;
- }
[poj1389.cpp]
- /*************************************************************************
- > File Name: poj1389.cpp
- > Author: cy
- > Mail: 1002@qq.com
- > Created Time: 14/10/14 11:02:43
- ************************************************************************/
- #include<iostream>
- #include<cstring>
- #include <algorithm>
- #include<cstdlib>
- #include<vector>
- #include<cmath>
- #include<stdlib.h>
- #include<iomanip>
- #include<list>
- #include<deque>
- #include<map>
- #include <stdio.h>
- #include <queue>
- #define maxn 5000+5
- #define inf 0x3f3f3f3f
- #define INF 0x3FFFFFFFFFFFFFFFLL
- #define rep(i,n) for(i=0;i<n;i++)
- #define reP(i,n) for(i=1;i<=n;i++)
- #define ull unsigned long long
- #define ll long long
- #define LL(x) x<<1
- #define RR(x) x<<1|1
- #define cle(a) memset(a,0,sizeof(a))
- using namespace std;
- struct Line{//扫描线
- double x,upy,downy;
- int flag;
- Line(double a,double b,double c,int d) : x(a), upy(b), downy(c), flag(d){}
- Line(){}
- }line[maxn];
- struct node{
- int l,r,flag;
- double ly,ry,len;
- int Mid(){
- return (l+r)>>1;
- }
- }tree[maxn<<2];
- double hash[maxn];
- bool cmp(Line a,Line b){return a.x<b.x;
- }
- void build(int rt,int l,int r){
- tree[rt].l=l,tree[rt].r=r;
- tree[rt].ly=hash[l],tree[rt].ry=hash[r];
- tree[rt].flag=0,tree[rt].len=0;
- if(tree[rt].l+1==tree[rt].r)return;
- int mid=(l+r)>>1;
- build(LL(rt),l,mid),build(RR(rt),mid,r);//右边为mid并非mid+1,
- }
- void doit(int x){//更新覆盖段
- if(tree[x].flag)tree[x].len=tree[x].ry-tree[x].ly;
- else if(tree[x].l+1==tree[x].r)tree[x].len=0;
- else tree[x].len=tree[RR(x)].len+tree[LL(x)].len;
- }
- void update(int rt,Line a){//更新
- if(a.upy==tree[rt].ly&&a.downy==tree[rt].ry){
- tree[rt].flag+=a.flag;
- doit(rt);return;
- }
- if(a.downy<=tree[LL(rt)].ry)update(LL(rt),a);
- else if(a.upy>=tree[RR(rt)].ly)update(RR(rt),a);
- else{
- Line temp=a;temp.downy=tree[LL(rt)].ry;
- update(LL(rt),temp);
- temp=a;temp.upy=tree[RR(rt)].ly;
- update(RR(rt),temp);
- }
- doit(rt);
- return;
- }
- bool getend(double a,double b,double c,double d){
- if(a==-1&&b==-1&&c==-1&&d==-1)return true;
- return false;
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("in.txt","r",stdin);
- //freopen("out.txt","w",stdout);
- #endif
- int i;
- double a,b,c,d;
- int T=1;
- while(true){
- while(scanf("%lf%lf%lf%lf",&a,&b,&c,&d)){
- if(getend(a,b,c,d)){
- break;
- }
- line[2*T-1]=Line(a,b,d,1);line[2*T]=Line(c,b,d,-1);
- hash[2*T-1]=b,hash[2*T]=d;
- T++;
- }
- if(T==1)return 0;
- T--;
- sort(line,line+2*T+1,cmp);sort(hash,hash+1+T*2);
- int m=2*T;
- build(1,1,m);update(1,line[1]);
- double ans=0.0;
- for(i=2;i<=m;i++){
- ans+=(tree[1].len)*(line[i].x-line[i-1].x);
- update(1,line[i]);
- }
- printf("%.0f\n",ans);
- T=1;
- }
- return 0;
- }