我觉得像我这样把所有东西都写的类的ACMer真是一个异类。。。
1 //Result:wizmann 1151 Accepted 832K 0MS G++ 3310B 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <algorithm> 6 #include <string> 7 #include <cmath> 8 #include <vector> 9 #include <set> 10 #include <map> 11 #include <iostream> 12 13 using namespace std; 14 15 #define print(x) cout<<x<<endl 16 #define input(x) cin>>x 17 #define SIZE 128 18 19 struct node 20 { 21 int st,end; 22 double len; 23 int cov; 24 25 node(){} 26 node(int ist,int iend,double ilen) 27 { 28 cov=0; 29 st=ist;end=iend; 30 len=ilen; 31 } 32 33 bool equal(int a,int b) 34 { 35 return st==a && end==b; 36 } 37 38 int getmid() 39 { 40 return (st+end)>>1; 41 } 42 43 bool endnode() 44 { 45 return end-st<=1; 46 } 47 }; 48 49 struct point 50 { 51 double x,y; 52 point(){} 53 point(double i_x,double i_y) 54 { 55 x=i_x;y=i_y; 56 } 57 }; 58 59 struct segment 60 { 61 point p1,p2; 62 63 segment(){} 64 segment(const point& a,const point& b) 65 { 66 p1=a;p2=b; 67 } 68 }; 69 70 struct line 71 { 72 double y; 73 int x1,x2; 74 int flag; 75 line(){} 76 line(int ix1,int ix2,double iy,int iflag) 77 { 78 x1=ix1;x2=ix2; 79 y=iy;flag=iflag; 80 } 81 friend bool operator < (const line& a,const line& b) 82 { 83 return a.y<b.y; 84 } 85 }; 86 87 const int ROOT=0; 88 89 90 node stree[SIZE<<2]; 91 int n; 92 map<double,int> hash; 93 map<int,double> anti_hash; 94 int sz,ind; 95 line edge[SIZE<<1]; 96 97 98 inline int left(int x) 99 { 100 return (x<<1)+1; 101 } 102 inline int right(int x) 103 { 104 return left(x)+1; 105 } 106 107 void stree_init(int l,int r,int pos=ROOT) 108 { 109 stree[pos]=node(l,r,anti_hash[r+1]-anti_hash[l]); 110 if(l<r) 111 { 112 int mid=(l+r)>>1; 113 stree_init(l,mid,left(pos)); 114 stree_init(mid+1,r,right(pos)); 115 } 116 } 117 118 void update(int l,int r,int cov,int pos=ROOT) 119 { 120 if(stree[pos].equal(l,r)) 121 { 122 stree[pos].cov+=cov; 123 } 124 else 125 { 126 int mid=stree[pos].getmid(); 127 if(r<=mid) update(l,r,cov,left(pos)); 128 else if(l>mid) update(l,r,cov,right(pos)); 129 else 130 { 131 update(l,mid,cov,left(pos)); 132 update(mid+1,r,cov,right(pos)); 133 } 134 } 135 } 136 137 double query(int pos=ROOT) 138 { 139 double res=0; 140 if(stree[pos].cov>0) res+=stree[pos].len; 141 else if(stree[pos].st!=stree[pos].end) 142 { 143 res+=query(left(pos)); 144 res+=query(right(pos)); 145 } 146 return res; 147 } 148 149 int main() 150 { 151 double bx,by,ex,ey; 152 int cas=1; 153 while(input(n) && n) 154 { 155 hash.clear(); 156 anti_hash.clear(); 157 vector<double> itemx; 158 vector<segment> seg; 159 for(int i=0;i<n;i++) 160 { 161 scanf("%lf%lf%lf%lf",&bx,&by,&ex,&ey); 162 itemx.push_back(bx); 163 itemx.push_back(ex); 164 seg.push_back(segment(point(bx,by),point(ex,by))); 165 seg.push_back(segment(point(bx,ey),point(ex,ey))); 166 } 167 sort(itemx.begin(),itemx.end()); 168 sz=itemx.size(); 169 ind=0; 170 double ans=0; 171 for(int i=0;i<sz;i++) 172 { 173 if(hash.find(itemx[i])==hash.end()) 174 { 175 //print(itemx[i]<<' '<<ind); 176 hash[itemx[i]]=ind; 177 anti_hash[ind]=itemx[i]; 178 ind++; 179 } 180 } 181 sz=seg.size(); 182 for(int i=0;i<(int)seg.size();i+=2) 183 { 184 edge[i]=line(hash[seg[i].p1.x],hash[seg[i].p2.x]-1,seg[i].p1.y,1); 185 edge[i+1]=line(hash[seg[i+1].p1.x],hash[seg[i+1].p2.x]-1,seg[i+1].p1.y,-1); 186 } 187 sort(edge,edge+sz); 188 stree_init(0,ind-1); 189 update(edge[0].x1,edge[0].x2,edge[0].flag); 190 for(int i=1;i<sz;i++) 191 { 192 ans+=fabs(edge[i-1].y-edge[i].y)*query(); 193 update(edge[i].x1,edge[i].x2,edge[i].flag); 194 } 195 printf("Test case #%d\n",cas++); 196 printf("Total explored area: %.2f\n\n",ans); 197 } 198 return 0; 199 }