Good algorithm for a query related problem

纵然是瞬间 提交于 2021-02-11 14:56:21

问题


Given N pairs, we have to find the count of pairs that contain an element k in their range, i.e :
If a Pairi is defined as (Xi,Yi), then if Pairi contain K in its range, then Xi <= K <= Yi.

Now we are given Q such queries to handle with each query consisting of an integer K.

Input: The first line contains two space-separated integers N and Q.
Next N lines follow where each line denotes a pair. Each line contains two space-separated integers.
Next Q lines follow where each line denotes an integer K

Output: We are to output the count of pairs where Xi i<= K <= Yi for each query

Constraints: 1 <= N,Q <= 105

Time limit: 2 s

Example:

Input-
4 2
1 5
2 5
6 10
7 8
7
9
Output-
2
1
Explanation-
First query K=7 holds for (6,10) and (7,8).
Second query K=9 holds for (6,10) only.

Given below is my code in java with complexity O(NQ).

import java.util.*;
class Query
{
    public static void main(String args[])
    {
        Scanner sc = new Scanner(System.in);
        int n,q;
        n = sc.nextInt();
        q = sc.nextInt();
        int x[] = new int[n];
        int y[] = new int[n];
        for(int i=0;i<n;i++)
        {
            x[i] = sc.nextInt();
            y[i] = sc.nextInt();
        }
        while(q-->0)
        {
            int k = sc.nextInt();
            int count = 0;
            for(int i = 0;i<n;i++)
            {
                if(x[i] <= k && k <= y[i])
                    count++;
            }
            System.out.println(count);
        }
    }
}

Can somebody provide me with an approach that has a better complexity such as O(N + Q log N)? I thought of using segment trees and such but do not if it would work for this problem and how to implement it here.


回答1:


A complexity O(NlogN + QlogN) can be obtained by performing a preprocessing before the queries themselves.

1st step: Preprocessing

The goal is to determine the number of intervals associated for each limit A[k] of each interval, and to sort these A[k].

This is performed in the following way: for each input interval [X, Y], the corresponding limits X and Y are put in a array, and we count the number of openings and closures for each limit X:

open[X] ++
close[Y] ++

The reason behind is that each value after X is "gaining'" one interval, and each value after Y is "losing" one interval.

Then, after sorting, the number of intervals of a given limit is obtained recursively:

After the limit: W[0] = n_opening[0], W[i] = W[i-1] + n_opening[i] - n_closure[i]
On the limit: WL[0] = n_opening[0], WL[i] = W[i-1] + n_opening[i]

This is better illustrated by an example. For the input intervals [1,5], [2, 5], [6, 10], [7, 8], the V[] values are given by:

 open[]   1   1   0   1   1   0   0
 close[]  0   0   2   0   0   1   1
       ---|---|---|---|---|---|---|---
          1   2   5   6   7   8   10

And the W[] and WL[] values are provided by

WL[]    1   2   2   1   2   2   1
W[]     1   2   0   1   2   1   0 
     ---|---|---|---|---|---|---|---
        1   2   5   6   7   8   10

2nd step: queries

For each query K, we have first to determine the corresponding interval [A[i], A[i+1]]. As the A[i] are sorted, this an be done in log(N). Then:

If K is outside any interval: m[k] = 0
If K is in the interval ]A[i], A[i+1][, i.e. not equal to any limit, then m[k] = W[A[i]]
if K is equal to a limit A[i], then m[k] = WL[a[i]]

In the previous example:

K = 7 -> m(7) = WL[7] = 2
K = 9 -> m(9) = W[8] = 1


来源:https://stackoverflow.com/questions/60643340/good-algorithm-for-a-query-related-problem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!