问题
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