【HDOJ1828&&POJ1177】Picture(线段树,扫描线)
题意:给定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\n",ans); 145 } 146 147 148 return 0; 149 } 150 151
null