Add a lb[],rb[] array to mark the vertical edges. Add num to calculate the number of vertical edges, because when the perimeter is calculated, the non-covered vertical edges are added
#include <stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>using namespacestd;#defineLson l,m,rt<<1#defineRson m+1,r,rt<<1|1#defineMAXN 10100BOOLlb[maxn<<2],rb[maxn<<2];structseg{intl,r,h; intF;} S[MAXN];structnode{intCNT; intnum; intLen;} TREE[MAXN<<2];intmark[maxn<<2];intMinintXinty) { returnX<y?x:y;}intMaxintXinty) { returnX>y?x:y;}BOOLcmp (seg a,seg b) {returna.h<b.h;}voidGetlen (intLintRintRT) { if(tree[rt].cnt) {Lb[rt]=rb[rt]=true;//Mark whether the vertical edge is being usedtree[rt].len=mark[r+1]-Mark[l]; Tree[rt].num=2; } Else if(l==r) Tree[rt].len=tree[rt].num=lb[rt]=rb[rt]=0; Else{Tree[rt].len=tree[rt<<1].len+tree[rt<<1|1].len; Tree[rt].num=tree[rt<<1].num+tree[rt<<1|1].num; LB[RT]=lb[rt<<1];rb[rt]=rb[rt<<1|1]; if(rb[rt<<1]&&lb[rt<<1|1])//The left child's right side and right child's left have been used. So these 2 bars don't need to be added.tree[rt].num-=2; }}voidUpdata (intLintRintCintLintRintRT) { if(l<=l&&r>=r) {tree[rt].cnt+=C; Getlen (L,R,RT); return ; } intM= (L+R)/2; if(m>=L) Updata (L,r,c,lson); if(r>m) updata (L,r,c,rson); Getlen (L,R,RT);}intFindintValintnum) { intl,r,m; L=0; r=num; while(l<=r) {m= (l+r)/2; if(val==Mark[m])returnm; Else if(val>Mark[m]) L=m+1; Elser=m-1; } return-1;}intMain () {intI,n,m,l,r; intX1,x2,y1,y2; while(SCANF ("%d", &n)! =EOF) {m=0; L=999999; R=-999999; memset (s),0,sizeof(s)); for(i=0; i<n;i++) {scanf ("%d%d%d%d",&x1,&y1,&x2,&y2); S[M].L=x1;s[m].r=x2;s[m].h=y1;mark[m]=x1;s[m++].f=1; S[M].L=x1;s[m].r=x2;s[m].h=y2;mark[m]=x2;s[m++].f=-1; } sort (Mark,mark+m); intk=1; for(i=1; i<m;i++) { if(mark[i]!=mark[i-1]) Mark[k++]=Mark[i]; } memset (Tree,0,sizeof(tree)); memset (LB,false,sizeof(lb)); Memset (RB,false,sizeof(RB)); Sort (s,s+m,cmp); intans=0, past=0; for(i=0; i<m;i++) { intLl=find (s[i].l,k-1); intRr=find (s[i].r,k-1)-1; Updata (LL,RR,S[I].F,0, K-1,1); Ans+=tree[1].num* (s[i+1].h-s[i].h); Ans+=abs (tree[1].len-past); Past=tree[1].len; } printf ("%d\n", ans); }}
hdu1828 Segment Tree + discretization + scan line