Skip to content

Commit d5c6e9b

Browse files
author
hzhuzheng
committed
plane sweep thinking
1 parent bfde1c4 commit d5c6e9b

File tree

6 files changed

+691
-0
lines changed

6 files changed

+691
-0
lines changed

plane-sweep-thinking/a.cpp

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#include<stdlib.h>
2+
#include<stdio.h>
3+
#include<string.h>
4+
#include<set>
5+
#include<iostream>
6+
#include<algorithm>
7+
#define maxn 5005
8+
using namespace std ;
9+
10+
struct seg_node{
11+
int l , r , mid ;
12+
int lbd , rbd , m , cnt , line ;
13+
};
14+
15+
struct event{
16+
int x , y0 , y1 , ty ;
17+
};
18+
19+
set<int> fuck ;
20+
set<int>::iterator it ;
21+
22+
seg_node t[6*maxn] ;
23+
event e[2*maxn] ;
24+
int es , posY[2*maxn], ps ;
25+
26+
inline int L(int x) { return x<<1 ; }
27+
inline int R(int x) { return (x<<1)|1 ;}
28+
inline int _abs(int x) { return x > 0 ? x : -x ; }
29+
30+
int bs(int x){
31+
int l = 1 , r = ps , mid ;
32+
while(l<=r){
33+
mid = (l+r)>>1 ;
34+
if(posY[mid] == x) return mid ;
35+
if(x < posY[mid] ) r = mid - 1;
36+
if(posY[mid] < x ) l = mid + 1;
37+
}
38+
return 0 ;
39+
}
40+
41+
bool cmp(event a , event b ){
42+
if(a.x != b.x ) return a.x < b.x ;
43+
return a.ty > b.ty ;
44+
}
45+
46+
void build(int x , int l ,int r ){
47+
t[x].l = l , t[x].r = r , t[x].m = t[x].cnt = t[x].line = t[x].lbd = t[x].rbd = 0 ;
48+
if(l+1 != r){
49+
int mid = (l + r)>>1 ;
50+
build(L(x) , l , mid );
51+
build(R(x) , mid , r );
52+
}
53+
}
54+
55+
void update(int x ){
56+
if(t[x].cnt > 0 ){
57+
t[x].lbd = t[x].rbd = t[x].line = 1 ;
58+
t[x].m = posY[t[x].r] - posY[t[x].l] ;
59+
}else if(t[x].l + 1 == t[x].r ){
60+
t[x].lbd = t[x].rbd = t[x].line = t[x].m = 0 ;
61+
}else{
62+
t[x].lbd = t[L(x)].lbd ;
63+
t[x].rbd = t[R(x)].rbd ;
64+
t[x].m = t[L(x)].m + t[R(x)].m ;
65+
t[x].line = t[L(x)].line + t[R(x)].line - t[L(x)].rbd * t[R(x)].lbd ;
66+
}
67+
}
68+
69+
void Insert(int x , int l , int r , int d){
70+
if(t[x].l == l && t[x].r == r){
71+
t[x].cnt +=d ;
72+
}else{
73+
int mid = (t[x].l + t[x].r)>>1 ;
74+
if(r <= mid ){
75+
Insert(L(x) , l , r , d );
76+
}else if(mid <= l ){
77+
Insert(R(x) , l , r , d );
78+
}else{
79+
Insert(L(x) , l , mid ,d);
80+
Insert(R(x) , mid, r ,d);
81+
}
82+
}
83+
update(x);
84+
}
85+
86+
int main(){
87+
88+
int N , i , x0 , y0 , x1 , y1 , last , ans ;
89+
90+
while(scanf("%d" , &N)!=EOF){
91+
92+
fuck.clear() ; es = 0 ;
93+
94+
for(i = 1 ; i<= N ; ++ i){
95+
scanf("%d%d%d%d" , &x0 , &y0 , &x1 , &y1);
96+
fuck.insert(y0); fuck.insert(y1);
97+
++es ; e[es].x = x0 ; e[es].y0 = y0 ; e[es].y1 = y1 ; e[es].ty = +1 ;
98+
++es ; e[es].x = x1 ; e[es].y0 = y0 ; e[es].y1 = y1 ; e[es].ty = -1 ;
99+
}
100+
101+
for(it = fuck.begin(), ps = 0 ; it!=fuck.end() ; it++)
102+
posY[++ps] = *it ;
103+
104+
sort(e+1 , e+es+1 , cmp);
105+
106+
build(1 , 1 , ps ); ans = last = 0 ;
107+
108+
for(i = 1 ; i < es ; ++ i){
109+
Insert(1 , bs(e[i].y0) , bs(e[i].y1) , e[i].ty );
110+
ans = ans + 2 * t[1].line * (e[i+1].x - e[i].x ) ;
111+
ans += _abs(t[1].m - last) ;
112+
last = t[1].m ;
113+
}
114+
ans += t[1].m ;
115+
116+
printf("%d\n" , ans);
117+
}
118+
//system("pause");
119+
return 0 ;
120+
}

plane-sweep-thinking/a1.cpp

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#include<stdio.h>
2+
#include<stdlib.h>
3+
#include<string.h>
4+
#include<math.h>
5+
#define L(x) ((x)<<1)
6+
#define R(x) (((x)<<1)|1)
7+
#define maxn 105
8+
9+
typedef struct{
10+
double x ,y0 ,y1 ;
11+
int type ;
12+
}event;
13+
typedef struct node{
14+
int l , r , cnt ;
15+
double m ;
16+
}node;
17+
18+
int n , ps , es ;
19+
double posY[2*maxn] , py[2*maxn] ;
20+
event e[2*maxn] ;
21+
node t[6*maxn] ;
22+
23+
int bs(double x){
24+
int l = 1 , r = ps , mid ;
25+
while(l<=r){
26+
mid = (l+r)>>1 ;
27+
if(posY[mid] == x) return mid ;
28+
if( x < posY[mid]) r = mid -1 ;
29+
if( x > posY[mid]) l = mid +1 ;
30+
}
31+
return 0 ;
32+
}
33+
34+
void double_sort(double *a , int l , int r){
35+
int i = l , j = r ;
36+
double x = a[(l+r)>>1] , temp ;
37+
if(l>=r) return ;
38+
do{
39+
while(a[i]<x) ++ i ;
40+
while(a[j]>x) -- j ;
41+
if(i<=j){
42+
temp = a[i] ; a[i] = a[j] ; a[j] = temp ;
43+
i++ ; j-- ;
44+
}
45+
}while(i<=j) ;
46+
if(i<r) double_sort(a , i , r);
47+
if(l<j) double_sort(a , l , j);
48+
}
49+
50+
int less(event a , event b){
51+
if(a.x != b.x ) return a.x < b.x ;
52+
return a.type > b.type ;
53+
}
54+
55+
void event_sort(event *a , int l ,int r){
56+
if(l>=r) return ;
57+
int i = l , j = r ;
58+
event x = a[(l+r)>>1] , temp ;
59+
do{
60+
while(less(a[i] , x)) ++ i ;
61+
while(less(x , a[j])) -- j ;
62+
if(i<=j){
63+
temp = a[i] ; a[i] = a[j] ; a[j] = temp ;
64+
++ i ; -- j ;
65+
}
66+
}while(i<=j) ;
67+
if(i<r) event_sort(a , i , r);
68+
if(l<j) event_sort(a , l , j);
69+
}
70+
71+
void update(int x){
72+
if(t[x].cnt){
73+
t[x].m = posY[t[x].r] - posY[t[x].l]; //printf("cedu:%0.2lf\n" , t[x].m);
74+
}else if(t[x].r-t[x].l==1){
75+
t[x].m = 0 ;
76+
}else{
77+
t[x].m = t[L(x)].m + t[R(x)].m ;
78+
}
79+
}
80+
81+
void segtree_build(int x , int l ,int r){
82+
int mid ;
83+
t[x].l = l , t[x].r = r , t[x].cnt = 0 , t[x].m = 0 ;
84+
if(r-l!=1){
85+
mid = (l+r)>>1 ;
86+
segtree_build(L(x) , l , mid);
87+
segtree_build(R(x) ,mid , r);
88+
}
89+
}
90+
91+
void segtree_insert(int x , int l , int r , int delta){
92+
int mid = (t[x].l + t[x].r)>>1 ;
93+
if(t[x].l == l && t[x].r == r){
94+
t[x].cnt += delta ;
95+
}else if(r<=mid){
96+
segtree_insert(L(x) , l , r , delta);
97+
}else if(mid<=l){
98+
segtree_insert(R(x) , l , r , delta);
99+
}else {
100+
segtree_insert(L(x) , l ,mid, delta);
101+
segtree_insert(R(x) ,mid, r, delta);
102+
}
103+
update(x);
104+
}
105+
106+
int main(){
107+
double x0 , y0 , x1 , y1 , area ;
108+
int i , cid = 0 , l , r ;
109+
while(scanf("%d" ,&n)!=EOF && n){
110+
es = ps = 0 ;
111+
for(i = 1 ; i<=n ;++i){
112+
scanf("%lf%lf%lf%lf" , &x0 , &y0 , &x1 , &y1);
113+
++ es ; e[es].x = x0 , e[es].y0 = y0 , e[es].y1 = y1 , e[es].type = +1 ; py[es] = y0 ;
114+
++ es ; e[es].x = x1 , e[es].y0 = y0 , e[es].y1 = y1 , e[es].type = -1 ; py[es] = y1 ;
115+
}
116+
double_sort(py , 1 , es);
117+
posY[1] = py[1] ; ps = 1 ;
118+
for(i = 2 ; i<=2*n ; ++ i)
119+
if(posY[ps]!=py[i]) posY[++ps] = py[i] ;
120+
event_sort(e , 1 , es);
121+
area = 0 ;
122+
123+
//for(i = 1 ; i<=ps; ++i) printf("posY[%d] = %0.2lf\n" , i , posY[i]);
124+
125+
segtree_build(1 , 1 , ps);
126+
for(i = 1 ; i <es ; ++ i){
127+
l = bs(e[i].y0) ; r = bs(e[i].y1);
128+
segtree_insert(1 , l , r , e[i].type);
129+
//printf("TYPE = %d ===== " , e[i].type);
130+
//printf("%0.2lf\n" , t[1].m);
131+
area += t[1].m * (e[i+1].x - e[i].x ) ;
132+
//printf("[%d , %d]\n" , l , r);
133+
}
134+
/**/
135+
printf("Test case #%d\nTotal explored area: %0.2lf\n\n" , ++cid , area) ;
136+
}
137+
//system("pause");
138+
return 0 ;
139+
}

plane-sweep-thinking/a2.cpp

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#include<iostream>
2+
#include<stdlib.h>
3+
#include<stdio.h>
4+
#include<set>
5+
#define maxn 30005
6+
using namespace std ;
7+
8+
typedef __int64 lld ;
9+
10+
struct rect{
11+
int x0 , y0 , x1 , y1 , h ;
12+
};
13+
14+
struct event{
15+
int x , y0 , y1 , type ;
16+
};
17+
18+
struct node{
19+
int l , r , cnt , m ;
20+
};
21+
22+
node t[6*maxn] ;
23+
event e[2*maxn] ;
24+
rect r[maxn] , Rt[maxn] ;
25+
set<int> win ;
26+
set<int>::iterator it ;
27+
int Height[4] , M , n , Rs , posY[2*maxn] , es , ps ;
28+
29+
inline bool cmp(event a , event b ){
30+
if(a.x != b.x ) return a.x < b.x ;
31+
return a.type > b.type ;
32+
}
33+
34+
inline int L(int x) { return x<<1 ; }
35+
inline int R(int x) { return (x<<1)|1 ; }
36+
37+
int bs(int x ){
38+
int l = 1 , r = ps , mid ;
39+
while(l<=r){
40+
mid = (l + r)>>1 ;
41+
if(posY[mid] == x ) return mid ;
42+
if(x < posY[mid] ) r = mid - 1;
43+
if(x > posY[mid] ) l = mid + 1;
44+
}
45+
return 0 ;
46+
}
47+
48+
void Build(int x , int l , int r){
49+
int mid ;
50+
t[x].l = l , t[x].r = r , t[x].cnt = t[x].m = 0 ;
51+
if(l + 1 != r){
52+
mid = (l + r)>>1 ;
53+
Build(L(x) , l , mid );
54+
Build(R(x) , mid , r );
55+
}
56+
}
57+
58+
void Update(int x ){
59+
if(t[x].cnt > 0 ){
60+
t[x].m = posY[t[x].r] - posY[t[x].l] ;
61+
}else if(t[x].l + 1 == t[x].r ){
62+
t[x].m = 0 ;
63+
}else {
64+
t[x].m = t[L(x)].m + t[R(x)].m ;
65+
}
66+
}
67+
68+
void Insert(int x ,int l , int r , int d ){
69+
if(t[x].l == l && t[x].r == r){
70+
t[x].cnt += d ;
71+
}else{
72+
int mid = (t[x].l + t[x].r)>>1 ;
73+
if(r <= mid )
74+
Insert(L(x) , l , r , d );
75+
else if(mid <= l)
76+
Insert(R(x) , l , r , d );
77+
else {
78+
Insert(L(x) , l , mid ,d);
79+
Insert(R(x) ,mid ,r , d);
80+
}
81+
}
82+
Update(x);
83+
}
84+
85+
lld calc_area(){
86+
int i , j ;
87+
lld area ;
88+
es =0 ; area = 0 ; win.clear() ;
89+
for(i = 1 ; i <= Rs ; ++i){
90+
win.insert(Rt[i].y0); win.insert(Rt[i].y1);
91+
++es ; e[es].x = Rt[i].x0 ; e[es].y0 = Rt[i].y0 ; e[es].y1 = Rt[i].y1 ; e[es].type = +1 ;
92+
++es ; e[es].x = Rt[i].x1 ; e[es].y0 = Rt[i].y0 ; e[es].y1 = Rt[i].y1 ; e[es].type = -1 ;
93+
}
94+
95+
for(it = win.begin() , ps = 0 ; it!=win.end() ; it ++ )
96+
posY[++ps] = *it ;
97+
98+
sort(e+1 , e+es+1 , cmp );
99+
100+
Build(1 , 1 , ps);
101+
102+
for(i = 1 ; i < es ; ++ i){
103+
Insert(1 , bs(e[i].y0) , bs(e[i].y1) , e[i].type );
104+
area += (lld)t[1].m * (lld)(e[i+1].x - e[i].x ) ;
105+
}
106+
return area ;
107+
}
108+
109+
int main(){
110+
int acase , i , h , cid = 0 ;
111+
lld ans , square ;
112+
scanf("%d" ,&acase );
113+
while(acase--){
114+
scanf("%d%d" , &n , &M);
115+
for(i = 1 ;i<=M ; ++i) scanf("%d" ,&Height[i]);
116+
for(i = 1 ; i<=n ; ++i){
117+
scanf("%d%d%d%d%d" , &r[i].x0 , &r[i].y0 , &r[i].x1 , &r[i].y1 , &r[i].h );
118+
r[i].h = Height[r[i].h] ;
119+
}
120+
sort(Height+1 , Height+M+1); //printf("%I64d");
121+
Height[0] = 0 ; ans = 0 ;
122+
for(h = 1 ; h <= M ; ++ h){
123+
Rs = 0 ;
124+
for(i = 1 ; i<=n ; ++ i)
125+
if(r[i].h >= Height[h]){
126+
Rt[++Rs] = r[i] ;
127+
}
128+
//printf("Rs : %I64d\n" ,Rs);
129+
square = calc_area() ; //printf("square : %d\n" , square);
130+
ans += square * (Height[h] - Height[h-1] ) ;
131+
}
132+
printf("Case %d: %I64d\n" , ++cid , ans );
133+
}
134+
//system("pause");
135+
return 0 ;
136+
}

0 commit comments

Comments
 (0)