线段树求面积并,面积交,周长

 

http://acm.hdu.edu.cn/showproblem.php?pid=1542

面积并

 1 #include<bits/stdc++.h>
 2 #define maxn 100005
 3 #define lson l,mid,rt<<1
 4 #define rson mid+1,r,rt<<1|1
 5 #define pb push_back
 6 using namespace std;
 7 
 8 double tree[maxn<<2];
 9 int lazy[maxn<<2];
10 vector<double>ve;
11 
12 struct seg{
13     double l,r,h;
14     int flag;
15     seg(){}
16     seg(double _l,double _r,double _h,int _flag){
17         l=_l,r=_r,h=_h,flag=_flag;
18     }
19     bool operator<(const seg &b)const{
20         return h<b.h;
21     }
22 }s[maxn];
23 
24 void push_up(int l,int r,int rt){
25     if(lazy[rt]){
26         tree[rt]=ve[r]-ve[l-1];
27     }
28     else if(l==r){
29         tree[rt]=0;
30     }
31     else{
32         tree[rt]=tree[rt<<1]+tree[rt<<1|1];
33     }
34 }
35 
36 void build(int l,int r,int rt){
37     tree[rt]=0,lazy[rt]=0;
38     if(l==r) return;
39     int mid=l+r>>1;
40     build(lson);
41     build(rson);
42 }
43 
44 void add(int L,int R,int v,int l,int r,int rt){
45     if(L<=l&&R>=r){
46         lazy[rt]+=v;
47         push_up(l,r,rt);
48         return;
49     }
50     int mid=l+r>>1;
51     if(L<=mid) add(L,R,v,lson);
52     if(R>mid) add(L,R,v,rson);
53     push_up(l,r,rt);
54 }
55 
56 int getid(double x){
57     return lower_bound(ve.begin(),ve.end(),x)-ve.begin()+1;
58 }
59 
60 int main(){
61     int n;
62     int Case=1;
63     while(~scanf("%d",&n)){
64         if(!n) break;
65         ve.clear();
66         int tot=0;
67         double x1,y1,x2,y2;
68         for(int i=1;i<=n;i++){
69             scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
70             ve.pb(x1),ve.pb(x2);
71             s[++tot]=seg(x1,x2,y1,1);
72             s[++tot]=seg(x1,x2,y2,-1);
73         }
74         sort(ve.begin(),ve.end());
75         ve.erase(unique(ve.begin(),ve.end()),ve.end());
76         sort(s+1,s+tot+1);
77         int N=ve.size();
78         build(1,N,1);
79         double ans=0;
80         for(int i=1;i<tot;i++){
81             int L=getid(s[i].l);
82             int R=getid(s[i].r)-1;
83             add(L,R,s[i].flag,1,N,1);
84             ans+=tree[1]*(s[i+1].h-s[i].h);
85         }
86         printf("Test case #%d\n",Case++);
87         printf("Total explored area: %.2f\n\n",ans);
88     }
89 }
View Code

 

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

面积交

  1 #include<bits/stdc++.h>
  2 #define maxn 100005
  3 #define lson l,mid,rt<<1
  4 #define rson mid+1,r,rt<<1|1
  5 #define pb push_back
  6 using namespace std;
  7 
  8 double tree[maxn<<2],tree2[maxn<<2];
  9 int lazy[maxn<<2];
 10 vector<double>ve;
 11 
 12 struct seg{
 13     double l,r,h;
 14     int flag;
 15     seg(){}
 16     seg(double _l,double _r,double _h,int _flag){
 17         l=_l,r=_r,h=_h,flag=_flag;
 18     }
 19     bool operator<(const seg &b)const{
 20         return h<b.h;
 21     }
 22 }s[maxn];
 23 
 24 void push_up(int l,int r,int rt){
 25     if(lazy[rt]){
 26         tree[rt]=ve[r]-ve[l-1];
 27     }
 28     else if(l==r){
 29         tree[rt]=0;
 30     }
 31     else{
 32         tree[rt]=tree[rt<<1]+tree[rt<<1|1];
 33     }
 34 }
 35 
 36 void push_up2(int l,int r,int rt){
 37     if(lazy[rt]>1){
 38         tree2[rt]=ve[r]-ve[l-1];
 39     }
 40     else if(l==r){
 41         tree2[rt]=0;
 42     }
 43     else if(lazy[rt]==1){
 44         tree2[rt]=tree[rt<<1]+tree[rt<<1|1];
 45     }
 46     else{
 47         tree2[rt]=tree2[rt<<1]+tree2[rt<<1|1];
 48     }
 49 }
 50 
 51 void build(int l,int r,int rt){
 52     tree[rt]=0,lazy[rt]=0;
 53     if(l==r) return;
 54     int mid=l+r>>1;
 55     build(lson);
 56     build(rson);
 57 }
 58 
 59 void add(int L,int R,int v,int l,int r,int rt){
 60     if(L<=l&&R>=r){
 61         lazy[rt]+=v;
 62         push_up(l,r,rt);
 63         push_up2(l,r,rt);
 64         return;
 65     }
 66     int mid=l+r>>1;
 67     if(L<=mid) add(L,R,v,lson);
 68     if(R>mid) add(L,R,v,rson);
 69     push_up(l,r,rt);
 70     push_up2(l,r,rt);
 71 }
 72 
 73 int getid(double x){
 74     return lower_bound(ve.begin(),ve.end(),x)-ve.begin()+1;
 75 }
 76 
 77 int main(){
 78     int n;
 79     int Case=1;
 80     int T;
 81     scanf("%d",&T);
 82     while(T--){
 83         scanf("%d",&n);
 84         ve.clear();
 85         int tot=0;
 86         double x1,y1,x2,y2;
 87         for(int i=1;i<=n;i++){
 88             scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
 89             ve.pb(x1),ve.pb(x2);
 90             s[++tot]=seg(x1,x2,y1,1);
 91             s[++tot]=seg(x1,x2,y2,-1);
 92         }
 93         sort(ve.begin(),ve.end());
 94         ve.erase(unique(ve.begin(),ve.end()),ve.end());
 95         sort(s+1,s+tot+1);
 96         int N=ve.size();
 97         build(1,N,1);
 98         double ans=0;
 99         for(int i=1;i<tot;i++){
100             int L=getid(s[i].l);
101             int R=getid(s[i].r)-1;
102             add(L,R,s[i].flag,1,N,1);
103             ans+=tree2[1]*(s[i+1].h-s[i].h);
104         }
105         printf("%.2f\n",ans);
106     }
107 }
View Code

 

http://acm.hdu.edu.cn/showproblem.php?pid=1828

求周长,两种方法

1.先求x轴再求y轴

 1 #include<bits/stdc++.h>
 2 #define maxn 100005
 3 #define lson l,mid,rt<<1
 4 #define rson mid+1,r,rt<<1|1
 5 #define pb push_back
 6 using namespace std;
 7 
 8 int tree[maxn<<2];
 9 int lazy[maxn<<2];
10 vector<int>ve[2];
11 int k;
12 
13 struct seg{
14     int l,r,h;
15     int flag;
16     seg(){}
17     seg(int _l,int _r,int _h,int _flag){
18         l=_l,r=_r,h=_h,flag=_flag;
19     }
20     bool operator<(const seg &b)const{
21         return h<b.h;
22     }
23 }s[maxn];
24 
25 void push_up(int l,int r,int rt){
26     if(lazy[rt]){
27         tree[rt]=ve[k][r]-ve[k][l-1];
28     }
29     else if(l==r){
30         tree[rt]=0;
31     }
32     else{
33         tree[rt]=tree[rt<<1]+tree[rt<<1|1];
34     }
35 }
36 
37 void build(int l,int r,int rt){
38     tree[rt]=0,lazy[rt]=0;
39     if(l==r) return;
40     int mid=l+r>>1;
41     build(lson);
42     build(rson);
43 }
44 
45 void add(int L,int R,int v,int l,int r,int rt){
46     if(L<=l&&R>=r){
47         lazy[rt]+=v;
48         push_up(l,r,rt);
49         return;
50     }
51     int mid=l+r>>1;
52     if(L<=mid) add(L,R,v,lson);
53     if(R>mid) add(L,R,v,rson);
54     push_up(l,r,rt);
55 }
56 
57 int getid(int x){
58     return lower_bound(ve[k].begin(),ve[k].end(),x)-ve[k].begin()+1;
59 }
60 
61 int main(){
62     int n;
63     while(~scanf("%d",&n)){
64         ve[0].clear();
65         ve[1].clear();
66         int x1,y1,x2,y2;
67         for(int i=1;i<=n;i++){
68             scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
69             ve[0].pb(x1),ve[0].pb(x2);
70             ve[1].pb(y1),ve[1].pb(y2);
71             s[i]=seg(x1,x2,y1,1);
72             s[i+n]=seg(x1,x2,y2,-1);
73             s[i+n+n]=seg(y1,y2,x1,1);
74             s[i+n+n+n]=seg(y1,y2,x2,-1);
75         }
76         int ans=0;
77         int pos=1;
78         for(k=0;k<2;k++){
79             sort(ve[k].begin(),ve[k].end());
80             ve[k].erase(unique(ve[k].begin(),ve[k].end()),ve[k].end());
81             sort(s+pos,s+pos+n+n);
82             int N=ve[k].size();
83             build(1,N,1);
84             int pre=0;
85             for(int i=pos;i<pos+n+n;i++){
86                 int L=getid(s[i].l);
87                 int R=getid(s[i].r)-1;
88                 add(L,R,s[i].flag,1,N,1);
89                 ans+=abs(tree[1]-pre);
90                 pre=tree[1];
91             }
92             pos+=n+n;
93         }
94         printf("%d\n",ans);
95     }
96 }
View Code

2.在求x轴的同时求y轴

  1 #include<bits/stdc++.h>
  2 #define maxn 100005
  3 #define lson l,mid,rt<<1
  4 #define rson mid+1,r,rt<<1|1
  5 #define pb push_back
  6 using namespace std;
  7 
  8 int heng[maxn<<2],shu[maxn<<2];
  9 int lazy[maxn<<2];
 10 bool Left[maxn<<2],Right[maxn<<2];
 11 vector<int>ve;
 12 
 13 struct seg{
 14     int l,r,h;
 15     int flag;
 16     seg(){}
 17     seg(int _l,int _r,int _h,int _flag){
 18         l=_l,r=_r,h=_h,flag=_flag;
 19     }
 20     bool operator<(const seg &b)const{
 21         return h<b.h;
 22     }
 23 }s[maxn];
 24 
 25 void push_up(int l,int r,int rt){
 26     if(lazy[rt]){
 27         heng[rt]=ve[r]-ve[l-1];
 28         shu[rt]=2;
 29         Left[rt]=Right[rt]=true;
 30     }
 31     else if(l==r){
 32         heng[rt]=0;
 33         shu[rt]=0;
 34         Left[rt]=Right[rt]=false;
 35     }
 36     else{
 37         heng[rt]=heng[rt<<1]+heng[rt<<1|1];
 38         shu[rt]=shu[rt<<1]+shu[rt<<1|1];
 39         Left[rt]=Left[rt<<1];
 40         Right[rt]=Right[rt<<1|1];
 41         if(Left[rt<<1|1]&&Right[rt<<1]){
 42             shu[rt]-=2;
 43         }
 44     }
 45 }
 46 
 47 void build(int l,int r,int rt){
 48     heng[rt]=0,shu[rt]=0,lazy[rt]=0;
 49     Left[rt]=false,Right[rt]=false;
 50     if(l==r) return;
 51     int mid=l+r>>1;
 52     build(lson);
 53     build(rson);
 54 }
 55 
 56 void add(int L,int R,int v,int l,int r,int rt){
 57     if(L<=l&&R>=r){
 58         lazy[rt]+=v;
 59         push_up(l,r,rt);
 60         return;
 61     }
 62     int mid=l+r>>1;
 63     if(L<=mid) add(L,R,v,lson);
 64     if(R>mid) add(L,R,v,rson);
 65     push_up(l,r,rt);
 66 }
 67 
 68 int getid(int x){
 69     return lower_bound(ve.begin(),ve.end(),x)-ve.begin()+1;
 70 }
 71 
 72 int main(){
 73     int n;
 74     while(~scanf("%d",&n)){
 75         ve.clear();
 76         int tot=0;
 77         int x1,y1,x2,y2;
 78         for(int i=1;i<=n;i++){
 79             scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
 80             ve.pb(x1),ve.pb(x2);
 81             s[++tot]=seg(x1,x2,y1,1);
 82             s[++tot]=seg(x1,x2,y2,-1);
 83         }
 84         sort(ve.begin(),ve.end());
 85         ve.erase(unique(ve.begin(),ve.end()),ve.end());
 86         sort(s+1,s+tot+1);
 87         int N=ve.size();
 88         build(1,N,1);
 89         int pre=0;
 90         int ans=0;
 91         for(int i=1;i<=tot;i++){
 92             int L=getid(s[i].l);
 93             int R=getid(s[i].r)-1;
 94             add(L,R,s[i].flag,1,N,1);
 95             ans+=shu[1]*(s[i+1].h-s[i].h);
 96             ans+=abs(heng[1]-pre);
 97             pre=heng[1];
 98         }
 99         printf("%d\n",ans);
100     }
101 }
View Code

 

posted on 2019-05-11 11:38  Fighting_sh  阅读(315)  评论(0编辑  收藏  举报

导航