1. 程式人生 > >HDU-1255 覆蓋的面積(線掃描)

HDU-1255 覆蓋的面積(線掃描)

space hdu for color trie body 長度 mes 不同的

鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1255

中文題意就不用再說了。

這是赤裸裸的線掃描問題,唯一不同的就是求得面積是覆蓋超過兩次的面積的大小。其實就是求覆蓋面積裏面多一個變量來存儲覆蓋一次的長度(HDU 1542)。

這裏有一個小小的坑點,要註意if語句判斷的順序。

  1 #include<cstdio>
  2 #include<algorithm>
  3 using namespace std;
  4 
  5 const int maxn=2018;
  6 int n;
  7 double x[maxn*2
]; 8 9 struct Line 10 { 11 double x1,x2,y; 12 operator<(const Line &a)const 13 { 14 return y<a.y; 15 } 16 int flag; 17 }line[maxn*2]; 18 19 struct Trie 20 { 21 int l,r;///線段樹的左右端點 22 double dl,dr;///左右端點的大小 23 double len1,len2;///覆蓋一次與兩次的長度 24
int cov;///被覆蓋的次數 25 }a[maxn*4]; 26 27 void Get_Len(int id) 28 { 29 if(a[id].cov>0) 30 a[id].len1=a[id].dr-a[id].dl; 31 else if(a[id].l+1==a[id].r) 32 a[id].len1=0; 33 else 34 a[id].len1=a[id*2].len1+a[id*2+1].len1; 35 36 if(a[id].cov>1) 37
a[id].len2=a[id].dr-a[id].dl; 38 else if(a[id].l+1==a[id].r)///(①) 39 a[id].len2=0; 40 else if(a[id].cov==1)///(②) 41 ///① ②兩個if語句交換了之後就是WA 42 ///先判斷①就是防止②語句的id*2可能不存在 43 a[id].len2=a[id*2].len1+a[id*2+1].len1; 44 else 45 a[id].len2=a[id*2].len2+a[id*2+1].len2; 46 } 47 void Build(int id,int l,int r) 48 { 49 a[id].cov=0; 50 a[id].dl=x[l]; 51 a[id].dr=x[r]; 52 a[id].l=l; 53 a[id].r=r; 54 a[id].len1=0; 55 a[id].len2=0; 56 if(l+1==r) 57 return ; 58 int mid=(l+r)/2; 59 Build(id*2,l,mid); 60 Build(id*2+1,mid,r); 61 62 } 63 void Updata(int id,Line e) 64 { 65 if(a[id].dl==e.x1&&a[id].dr==e.x2) 66 { 67 a[id].cov+=e.flag; 68 Get_Len(id); 69 return ; 70 } 71 72 if(a[id*2].dr>=e.x2) 73 Updata(id*2,e); 74 else if(a[id*2+1].dl<=e.x1) 75 Updata(id*2+1,e); 76 else 77 { 78 Line tep=e; 79 tep.x2=a[id*2].dr; 80 Updata(id*2,tep); 81 82 tep=e; 83 tep.x1=a[id*2+1].dl; 84 Updata(id*2+1,tep); 85 } 86 Get_Len(id); 87 } 88 89 int main() 90 { 91 int t; 92 scanf("%d",&t); 93 while(t--) 94 { 95 scanf("%d",&n); 96 int cnt=0; 97 for(int i=1;i<=n;i++) 98 { 99 double x1,y1,x2,y2; 100 scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2); 101 cnt++; 102 line[cnt].x1=x1; 103 line[cnt].x2=x2; 104 line[cnt].y=y1; 105 line[cnt].flag=1; 106 x[cnt]=x1; 107 108 cnt++; 109 line[cnt].x1=x1; 110 line[cnt].x2=x2; 111 line[cnt].y=y2; 112 line[cnt].flag=-1; 113 x[cnt]=x2; 114 } 115 sort(x+1,x+1+cnt); 116 sort(line+1,line+1+cnt); 117 Build(1,1,cnt); 118 Updata(1,line[1]); 119 double ans=0; 120 for(int i=2;i<=cnt;i++) 121 { 122 123 ans+=a[1].len2*(line[i].y-line[i-1].y); 124 Updata(1,line[i]); 125 } 126 printf("%.2f\n",ans); 127 } 128 return 0; 129 }

HDU-1255 覆蓋的面積(線掃描)