[Beauty of programming] interval coincidence judgment (line segment tree)

Source: Internet
Author: User

I. Problem:

1. given a source interval [x, y] and N unordered target intervals [X1, Y1] [X2, y2]... [XN, yn]: determines whether the source interval [x, y] is within the target interval.

2. Specify a window area and N windows on the system interface to determine whether the window area is overwritten by an existing window.


Ii. solution:

Question 1:

Use the left Boundary Value of the range to sort the target range by O (nlogn), merge the sorted range by O (n), and query the source range to be searched, use two points to find out the Oracle (logn) in which the left and right nodes are in the merged source range. If the node belongs to the same source range, it indicates that the node is in the target range. Otherwise, it indicates that the node is not in the target range.

# Include <iostream> # include <algorithm> using namespace STD; struct line {int low, high; bool operator <(const line & L) const {return low <L. low ;};# define maxn 10001 line lines [maxn]; // The destination interval int ncnt = 0; // Number of merged intervals # define n 101 line SL [N]; // The source interval to be queried // The interval where the key is located in binary search, int getindex (INT key) {int U, V; u = 0; V = ncnt-1; while (U <= V) // U, V can be equal to {int M = (U + V)> 1; if (Key> = lines [M]. low) u = m + 1; elsev = m-1;} return V;} int main () {int N, K, I, j; CIN> N> K; // n is the number of target intervals, and K is the number of source intervals to be queried for (I = 0; I <n; I ++) CIN> lines [I]. low> lines [I]. high; for (I = 0; I <K; I ++) CIN> SL [I]. low> SL [I]. high; // sort o (nlogn) sort (lines, lines + n); // merge O (n) int lasthigh = lines [0]. high; for (I = 1; I <n; I ++) if (lasthigh> = lines [I]. low) lasthigh = lines [I]. high; else {lines [ncnt ++]. high = lasthigh; lines [ncnt]. low = lines [I]. low; lasthigh = lines [I]. high;} lines [ncnt ++]. high = lasthigh; for (I = 0; I <K; I ++) {// word search time O (logn) int S1 = getindex (SL [I]. low); int S2 = getindex (SL [I]. high); If (S1 = S2 & SL [I]. high <= lines [s2]. high) printf ("Yes \ n"); elseprintf ("NO \ n ");}}

 

Method 2: UseQuery set, Merge each interval into a subtree, and finally determine whether the root of x and y in the source interval is the same.

# Include <iostream> using namespace STD; const int size = 100; int father [size]; int rank [size]; void make_set (int n) {for (INT I = 1; I <= N; I ++) {FATHER [I] = I; rank [I] = 1 ;}} int find_set (INT X) // find the representative element {If (X! = Father [x]) {// The element is not a separate segment. In a specific interval, a returned range represents father [x] = find_set (father [x]);} return father [X];} void Union (int x, int y) {x = find_set (x); y = find_set (y); If (x = y) {// return;} If (rank [x] <rank [y]) {FATHER [x] = y ;} else {FATHER [y] = x; If (rank [x] = rank [y]) {rank [x] ++ ;}} int main () {int X1, Y1; CIN> x1> Y1; // input the int X, Y; int N; CIN> N; // Number of intervals make_set (size); While (n --) {CIN> x> Y; // enter if (x> Y) for each interval) {// this step is critical, indicating thoughtful swap (x, y);} For (INT I = x + 1; I <= y; I ++) {// merge the segments in the interval to the existing range Union (x, I) ;}} if (find_set (X1) = find_set (Y1 )) {cout <"yes" <Endl;} else {cout <"no" <Endl;} system ("pause ");}

(1, 3) after combination, Father [1-3] = 1 rank [1] = 2; the remaining values are 1

(2, 4) fahter [1-4] = 1 rank [1] = 2 after combination; other values are 1

Description: (1, 4) indicates the entire interval, which is 1.

 

Method 3: Sort unordered target intervals, merge them into several ordered intervals, and compare the source interval with the ordered target interval.

 

# Include <iostream> # include <vector> using namespace STD; typedef pair <int, int> section; bool CMP (section A, Section B) {return. first <B. first;} int main () {Section SRC, TMP; CIN> SRC. first> SRC. second; // The vector <section> V; while (CIN> TMP. first> TMP. second, TMP. first | TMP. second) {v. push_back (TMP);} Sort (v. begin (), V. end (), CMP); // sort the vector <section> res; vector <sectio N>: iterator it = v. begin (); int begin = it-> first; // start part of the record interval int end = it-> second; // The starting part of the record interval if (IT + 1) = v. end () // if there is only one interval res. push_back (make_pair (begin, end); else {It ++; For (; it! = V. end (); It ++) {If (end <= it-> first) {// if the second element of the first pair is smaller than the first element of the next pair. Res. push_back (make_pair (begin, end); // Insert the first interval begin = it-> first; end = it-> second ;} else if (end> it-> first) & (end <= it-> second) {// res. push_back (make_pair (begin, end); // Insert the first interval // begin = it-> first; end = it-> second; If (IT + 1) = v. end () res. push_back (make_pair (begin, end) ;}} bool solve = false; it = res. begin (); For (; it! = Res. end (); It ++) {If (SRC. first> = it-> first & SRC. second <= it-> second) {solve = true; break ;}} if (solve) {cout <"in" <Endl ;} else {cout <"out" <Endl;} system ("pause ");}

 

Solution 2:

This problem is suitable for solving using the line segment tree. the time complexity of a single search is O (nlogn), and of course it can be answered using arrays, however, the time complexity of a single query increases to O (N ^ 2 ). Here we use the line segment tree to answer this question.

A line segment tree is a binary tree that divides the number axes into a series of elementary intervals [I, I + 1] (I =,..., N-1 ). Each elementary interval corresponds to a leaf node of a line segment tree. The internal node of a line segment tree corresponds to a general interval in the shape of [I, j] (j-I> 1. Because the line segment tree assigns nodes to each interval, we can use the line segment tree to calculate the total length of the interval and the number of line segments after the interval. The test data is provided first (the first four rows are the existing n windows on the system interface, and the last row is the window area to be tested), followed by the Code:

4
-15 0 5 10
-5 8 20 25
15-4 24 14
0-6 16 4

2 15 10 22

# Include <iostream> # include <cmath> # include <algorithm> using namespace STD; // struct segnode {int low, high; // The index int ncover on both ends of the line segment; // The number of times the line segment is overwritten segnode * left; // The left subtree segnode * Right of the node; // right subtree segnode () {LOW = high = 0; ncover = 0; left = right = NULL ;}; // construct a line segment tree, it is a complete Binary Tree void buildsegtree (segnode * & tree, int * index, int low, int high) {If (low 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.