Title Link: http://poj.org/problem?id=1436
Test instructions: Give some segments parallel to the Y axis in the first quadrant (which may also be on the Y axis), telling you where the line segment corresponds to the x-axis position xi, and the line segment corresponding to the y-axis of the YI1,YI2.
- If two segments can be connected with a segment of a parallel x-axis and the segment does not intersect other vertical segments, the two segments are said to be visible.
- If there are three vertical segments 22 visible, a segment triangle is formed.
The number of segment triangles in all segments that are given.
Idea: Construct a line segment tree on the y-axis to query which segment [L,r] is covered by. If the interval [l,r] is covered by more than one segment, you do not need to store all the segments. You can sort x first, update it sequentially, so that the interval [l,r] is overwritten by which segment of the previous line, only when you are looping to the current segment. Note that the value of y also needs to be multiplied . You can query whether the current segment and the previous segment are visible before each update. If the interval [l,r] is overridden by a segment, the segment now enumerated is visible to the covered segment (an array can be used to record 22 visible cases between the segments, and the final brute-force solution is the answer).
The code is as follows
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <queue>using namespace STD;#define Lson L, M, RT << 1#define Rson m + 1, R, RT << 1 | 1Const intN =8010;structSegment {intXintYs, ye;friend BOOL operator< (Segment A, Segment b) {if(a.x! = b.x)returna.x > b.x;Else if(A.ys! = B.ys)returnA.ys > B.ys;returnA.ye > B.ye; }};intN Segment Se[n];intA[n <<3];intLazy[n <<3];BOOLVisble[n][n];voidPushup (intRT) {if(A[rt <<1] = = A[rt <<1|1]) A[rt] = A[rt <<1];ElseA[RT] =-1;}voidPushdown (intRT) {if(LAZY[RT]! =-1) {Lazy[rt <<1] = Lazy[rt <<1|1] = Lazy[rt]; A[rt <<1] = A[rt <<1|1] = Lazy[rt]; LAZY[RT] =-1; }}voidUpdateintPintLintRintRT) {if(Se[p].ys <= l && R <= Se[p].ye) {A[rt] = p; LAZY[RT] = p;return; }if(L = = r)return; Pushdown (RT);intm = (L + r) >>1;if(Se[p].ys <= m) update (p, Lson);if(Se[p].ye > M) update (p, Rson); Pushup (RT);}voidQueryintPintLintRintRT) {if(A[rt] = =0)return;if(A[rt]! =0&& A[RT]! =-1) {Visble[a[rt]][p] =true;return; }if(L = = r)return; Pushdown (RT);intm = (L + r) >>1;if(Se[p].ys <= m) query (p, Lson);if(Se[p].ye > M) query (p, Rson); Pushup (RT);}intMain () {intT_case;scanf("%d", &t_case); for(intI_case =1; I_case <= t_case; i_case++) {memset(Lazy,-1,sizeof(lazy));memset(Visble,false,sizeof(visble));memsetA0,sizeof(a));scanf("%d", &n); for(inti =1; I <= N; i++) {scanf("%d%d%d", &se[i].ys, &se[i].ye, &se[i].x); Se[i].ys <<=1; Se[i].ye <<=1; } sort (Se +1, Se + n +1); for(inti =1; I <= N; i++) {Query (I,1, N <<1,1); Update (I,1, N <<1,1); }intCO =0; for(inti =1; I <= N; i++) { for(intj =1; J <= N; J + +) {if(Visble[i][j]) { for(intK =1; K <= N; k++) {if(Visble[i][k] && visble[k][j]) co++; } } } }printf("%d\n", CO); }return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
POJ 1436 Horizontally Visible segments