Calculate the perimeter of a malformed area
Compared to the area of the scan to trouble, the reason is in the non-overlapping area of the processing, the same height may be repeated overlay
So there are three more things to maintain in the nodes of a line tree:
Times: Interval numbers that do not overlap in intervals
For example, the first interval is the 2~6, the second is the 9~10, the third is the synthesis of 1~6, and the third independent, then the whole times is 2
In order to maintain the times, we need to LBD and RBD two variables, respectively, as the flag of whether or not the end of the interval is overwritten
Some blogs put these two variables into the bool type, these are not good, in the operation will cause trouble, we directly with int 0 and 1 will be better. So only in the left child's rbd* right child's lbd! =0, it means two kids. One more coverage when connected
The most important thing about the sensation of the scan line is that even if the updated impact is passed on
There is one more crucial thing is the understanding of discretization
My discretization is: think of each x and the interval between it and the next X as a whole
Like 1, 5, 83 points.
After discretization, 1 means 1~5,2 represents 5~8
It should be noted that only discrete n-1 points are required, because the right side of the last point is no length
So when a node in a segment tree has a representation interval of one or both, the length of this interval should be 1~8 (1~5+5~8)
Specific look at the code
#include"Cstdio"#include"Queue"#include"Cmath"#include"Stack"#include"iostream"#include"algorithm"#include"CString"#include"Queue"#include"Map"#include"Set"#include"Vector"#definell Long Long#defineMEMS (A, B) memset (A,b,sizeof (a))#defineLS pos<<1#defineRS Pos<<1|1using namespacestd;Const intMAXN = 1e5+ -;Const intMAXQ =10050;Const intINF =0x3f3f3f3f;intn,m;intX[MAXN];structline{intl,r,h,w; Line () {} line (intAintBintCintd): L (a), R (b), H (c), W (d) {}}LINE[MAXN];BOOLCMP (line A,line b) {returna.h<b.h;}structnode{intL,r; intLen; intCNT; intTimes ; intW; intLBD,RBD;} NODE[MAXN<<2];voidBuildintLintRintPOS) {NODE[POS].L=M; NODE[POS].R=R; Node[pos].cnt=node[pos].w=node[pos].times=0; NODE[POS].LBD=node[pos].rbd=0; Node[pos].len=x[node[pos].r+1]-X[NODE[POS].L]; if(L==R)return; intMid= (l+r) >>1; Build (L,mid,ls); Build (Mid+1, R,rs);}voidPushup (intPOS) { if(node[pos].w>0) {node[pos].cnt=Node[pos].len; NODE[POS].LBD=node[pos].rbd=node[pos].times=1; } Else if(node[pos].l==NODE[POS].R) {node[pos].cnt=0; NODE[POS].LBD=node[pos].rbd=node[pos].times=0; } Else{node[pos].cnt=node[ls].cnt+node[rs].cnt; NODE[POS].LBD=NODE[LS].LBD; NODE[POS].RBD=NODE[RS].RBD; Node[pos].times=node[ls].times+node[rs].times-node[rs].lbd*NODE[LS].RBD; }}intGet_pos (intW) { intlow=0, high=M,mid,ans; while(low<=High ) {Mid= (Low+high) >>1; if(X[MID]==W)returnmid; Else if(x[mid]>w) high=mid-1; ElseLow=mid+1; }}voidUpdateintLintRintPosintW) { if(l<=node[pos].l&&node[pos].r<=R) {NODE[POS].W+=W; Pushup (POS); return; } intMid= (NODE[POS].L+NODE[POS].R) >>1; if(l<=mid) Update (L,R,LS,W); if(r>mid) Update (L,R,RS,W); Pushup (POS);}intMain () {//freopen ("In.txt", "R", stdin); while(~SCANF ("%d",&N)) { for(intI=0;i<2*n;i+=2){ intX1,y1,x2,y2; scanf ("%d%d%d%d",&x1,&y1,&x2,&y2); Line[i]=line (X1,x2,y1,1); Line[i+1]=line (x1,x2,y2,-1); X[i]=X1; X[i+1]=x2; } sort (Line,line+2*n,cmp); Sort (x,x+2*N); M=0; for(intI=1;i<2*n;i++)if(x[i]!=x[i-1]) x[++m]=X[i]; Build (0, M-1,1); intans=0; intPre=0; for(intI=0;i<2*n-1; i++){ intL=Get_pos (LINE[I].L); intR=get_pos (LINE[I].R)-1; Update (L,R,1, LINE[I].W); Ans+=2*node[1].times* (line[i+1].h-line[i].h); Ans+=abs (node[1].cnt-pre); Pre=node[1].cnt; } ans+=line[2*n-1].r-line[2*n-1].L; printf ("%d\n", ans); } return 0;}
View Code
POJ 1177: Segment tree discrete scan line