Topic Link: Click to open the link
Test instructions: N vertical segments, which are visible if they are visible between two segments (that is, they can be connected with a horizontal segment without touching other segments). If any two bars of the three segments are visible, they are called a triangle of segments, and the number of a triangle of segments is obtained.
Idea: At first I did not think the complexity of n^3 can be too ... If so, the crux of the problem is how to determine whether any two segments are visible.
Then, if the y-coordinate is established, this becomes the interval coverage problem of the segment tree.
In addition, because it is a point instead of a line segment, so for the "visible" problem, there will be problems, such as three line segments [1,4], [up], [3,4], you can see in the [1,4] interval 3 line segments, that is, you can see through [2,3] the gap of the first line segment. The solution is simple, expand the coordinates twice times the line, so [to] become [2,4],[3,4] into [6,8], empty out of a 5.
See the code for details:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include < string> #include <vector> #include <stack> #include <bitset> #include <cstdlib> #include < cmath> #include <set> #include <list> #include <deque> #include <map> #include <queue># Define MAX (a) > (b)? ( A):(B) #define MIN (a) < (b) ( A):(B)) using namespace Std;typedef long Long ll;const double PI = ACOs ( -1.0); const double EPS = 1e-6;const int mod = 10000 00000 + 7;const int INF = 1000000000;const int MAXN = 8000 + 10;int T,n,t,q,l,r,c,col[maxn<<3],y[maxn<<1];bool vis[maxn][maxn];struct Node {int ly, ry, X; Node (int l=0, int r=0, int xx=0): ly (L), Ry (R), X (XX) {} bool operator < (const node& RHS) Const {return x < Rhs.x | | (x = = rhs.x && ly < rhs.ly); }}a[maxn];void pushdown (int o) {if (Col[o] >= 0) {col[o<<1] = col[o<<1|1] = Col[o]; Col[o] =-1;}}void Update (int l, int r, int c, int l, int r, int o) {int m = (L + R) >> 1; if (l <= l && R <= R) {Col[o] = C; return; } pushdown (o); if (l <= m) update (L, R, C, L, M, o<<1); if (M < R) Update (L, R, C, M+1, R, o<<1|1);} void query (int l, int r, int id, int l, int r, int o) {int m = (L + R) >> 1; if (Col[o] >= 0) {Vis[id][col[o]] = true; return; } if (L = = r) return; if (l <= m) query (L, R, ID, L, m, o<<1); if (M < R) query (L, R, ID, m+1, R, o<<1|1);} int main () {scanf ("%d", &t); while (t--) {scanf ("%d", &n); int m = 0; for (int i=0;i<n;i++) {scanf ("%d%d%d", &a[i].ly, &a[i].ry, &a[i].x); m = max (M, Max (a[i].ly, A[i].ry)); } sort (A, a+n); memset (col,-1, sizeof (COL)); Memset (Vis, false, sizeof (VIS)); for (int i=0;i<n;i++) {int L = a[i].ly; int r = A[i].ry; Query (2*l, 2*r, I, 0, 2*m, 1); Update (2*l, 2*r, I, 0, 2*m, 1); } int ans = 0; for (int i=n-1;i>=0;i--) {to (int j=i-1;j>=0;j--) {if (Vis[i][j]) {for (int k=j-1;k>=0;k--) {if (Vis[i][k] && vis[j][k]) ++ans; }}}} printf ("%d\n", ans); } return 0;}
POJ 1436 horizontally Visible segments (segment tree interval modified)