HDOJ1828&&POJ1177Picture(线段树,扫描线)

Posted myx12345

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ1828&&POJ1177Picture(线段树,扫描线)相关的知识,希望对你有一定的参考价值。

题意:给定n个矩形,求他们的并的周长

n<=5e3,abs(x[i])<=1e4

思路:From https://www.cnblogs.com/kuangbin/archive/2013/04/10/3013437.html

真实“线段”树

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #include<vector>
 11 using namespace std;
 12 typedef long long ll;
 13 typedef unsigned int uint;
 14 typedef unsigned long long ull;
 15 typedef pair<int,int> PII;
 16 typedef vector<int> VI;
 17 #define fi first
 18 #define se second
 19 #define MP make_pair
 20 #define N   11000
 21 #define M   7010
 22 #define eps 1e-8
 23 #define pi  acos(-1)
 24 #define oo  1e9
 25 #define MOD 10007
 26 
 27 struct node
 28 {
 29     int l,r,cnt,num,c;
 30     bool lc,rc;
 31 }t[N<<2];
 32 
 33 struct Line
 34 {
 35     int x1,x2,y,f;
 36 }line[N];
 37 
 38 bool cmp(Line a,Line b)
 39 {
 40     return a.y<b.y;
 41 }
 42 
 43 int x[N];
 44 
 45 void build(int l,int r,int p)
 46 {
 47     t[p].l=x[l];
 48     t[p].r=x[r];
 49     t[p].cnt=t[p].num=t[p].c=0;
 50     t[p].lc=t[p].rc=false;
 51     if(l+1==r) return;
 52     int mid=(l+r)>>1;
 53     build(l,mid,p<<1);
 54     build(mid,r,p<<1|1);
 55 }
 56 
 57 void calc(int p)
 58 {
 59     if(t[p].c>0)
 60     {
 61         t[p].cnt=t[p].r-t[p].l;
 62         t[p].num=1;
 63         t[p].lc=t[p].rc=true;
 64         return;
 65     }
 66     if(t[p].l+1==t[p].r)
 67     {
 68         t[p].cnt=t[p].num=0;
 69         t[p].lc=t[p].rc=false;
 70     }
 71      else
 72      {
 73          t[p].cnt=t[p<<1].cnt+t[p<<1|1].cnt;
 74          t[p].lc=t[p<<1].lc;
 75          t[p].rc=t[p<<1|1].rc;
 76          t[p].num=t[p<<1].num+t[p<<1|1].num;
 77          if(t[p<<1].rc&&t[p<<1|1].lc) t[p].num--;
 78      }
 79 }
 80 
 81 void update(int l,int r,Line e,int p)
 82 {
 83     if(t[p].l==e.x1&&t[p].r==e.x2)
 84     {
 85         t[p].c+=e.f;
 86         calc(p);
 87         return;
 88     }
 89     int mid=(l+r)>>1;
 90     if(e.x2<=t[p<<1].r) update(l,mid,e,p<<1);
 91      else if(e.x1>=t[p<<1|1].l) update(mid,r,e,p<<1|1);
 92       else 
 93       {
 94           Line tmp=e;
 95           tmp.x2=t[p<<1].r;
 96           update(l,mid,tmp,p<<1);
 97           tmp=e;
 98           tmp.x1=t[p<<1|1].l;
 99           update(mid,r,tmp,p<<1|1);
100       }
101     calc(p);
102 }
103 
104 int main()
105 {
106     //freopen("poj1177.in","r",stdin);
107     //freopen("poj1177.out","w",stdout); 
108     int n;
109     while(scanf("%d",&n)!=EOF)
110     {
111         int cnt=0;
112         for(int i=0;i<=n-1;i++)
113         {
114             int x1,y1,x2,y2;
115             scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 
116             line[cnt].x1=x1;
117             line[cnt].x2=x2;
118             line[cnt].y=y1;
119             line[cnt].f=1;
120             x[cnt++]=x1;
121             line[cnt].x1=x1;
122             line[cnt].x2=x2;
123             line[cnt].y=y2;
124             line[cnt].f=-1;
125             x[cnt++]=x2;
126         }
127         sort(line,line+cnt,cmp);
128         sort(x,x+cnt);
129         int m=unique(x,x+cnt)-x;
130         build(0,m-1,1); 
131     
132         int ans=0;
133         int last=0;
134         for(int i=0;i<cnt-1;i++)
135         {
136             update(0,m-1,line[i],1);
137             
138             ans+=t[1].num*2*(line[i+1].y-line[i].y);
139             ans+=abs(t[1].cnt-last);
140             last=t[1].cnt;
141         }
142         update(0,m-1,line[cnt-1],1);
143         ans+=abs(t[1].cnt-last);
144         printf("%d
",ans);
145     }
146             
147             
148     return 0;
149 }
150     
151     

 

以上是关于HDOJ1828&&POJ1177Picture(线段树,扫描线)的主要内容,如果未能解决你的问题,请参考以下文章

HDOJ图论题集

HDOJ 1828 线段树 矩形周长并

[HDOJ1828]Picture(扫描线,线段树,矩形并周长)

[POJ1177]Picture

poj1177 Picture

POJ1177 Picture.md