对于 Q 查询,X 和 Y 之间降雨量超过 K cms 的位置计数
给定一个由N个三元组(开始、结束、以 cms 为单位的降雨)组成的数组arr[][] ,定义降雨将从开始位置下降到结束位置,并以给定的降雨强度(以 cms 为单位)。还以数组query[][]的形式给出整数K和Q查询(在每个查询中给出X和Y )。对于每个查询,任务是查找X和Y (含)之间降雨量超过K cms 的位置数量。
例子:
Input: arr[][] = {{1, 3, 5}, {2, 8, 3}, {5, 8, 2}, {7, 9, 6}}, K = 5, query[][] ={{1, 5}, {5, 9}, {2, 9}, {1, 9}}
Output: 4, 5, 7, 8
Explanation: The aggregate array for given locations will be: 5 8 8 3 5 5 11 11 6 1 2 3 4 5 6 7 8 9
The aggregate array tells about the amount of rainfall in each location.
From locations 1 to 5, { 1, 2, 3, 5 } have rainfall >= 5 cms, Therefore answer is 4.
From locations 5 to 9, { 5, 6, 7, 8, 9 } have rainfall >= 5 cms, Therefore answer is 5.
From locations 2 to 9, { 2, 3, 5, 6, 7, 8, 9 } have rainfall >= 5 cms, Therefore answer is 7.
From locations 1 to 9, { 1, 2, 3, 5, 6, 7, 8, 9 } have rainfall >= 5 cms, Therefore answer is 9.
Input: arr[][] = {{2, 4, 1 }, {3, 9, 3}}, K = 5, query[][] ={{2, 5}, {4, 6}}
Output: 3, 3
朴素的做法:遍历数组arr[][]并找到 location 的最大值。创建一个大小等于找到的最大位置的数组。然后对于每个降雨范围更新数组以获得聚合数组。现在对于每个查询遍历形成的数组并计算降雨量大于K cms 的位置数。
下面是上述方法的代码。
C++
// C++ program for above approach
#include
using namespace std;
// Function to find number of locations
// with rainfall more than K cms
vector count(vector arr, vector > Q,
int q, int k)
{
vector ans;
for (int i = 0; i < q; i++) {
int temp = 0;
for (int j = Q[i][0]; j <= Q[i][1]; j++) {
if (arr[j] >= k)
temp++;
}
ans.push_back(temp);
}
return ans;
}
// Function to find aggregate array
vector aggregateArray(vector > arr, int n)
{
// To store the maximum location
int m = 0;
for (int i = 0; i < n; i++)
m = max(m, arr[i][1]);
// Array to store the aggregate values
vector agg(m + 1);
for (int i = 0; i < n; i++) {
for (int j = arr[i][0]; j <= arr[i][1]; j++) {
agg[j] += arr[i][2];
}
}
return agg;
}
// Driver Code
int main()
{
int N = 4;
vector > arr = {
{ 1, 3, 5 }, { 2, 8, 3 }, { 5, 8, 2 }, { 7, 9, 6 }
};
// Storing aggregate array
vector agg = aggregateArray(arr, N);
int Q = 4;
vector > queries
= { { 1, 5 }, { 5, 9 }, { 2, 9 }, { 1, 9 } };
int K = 5;
vector ans = count(agg, queries, Q, K);
// Printing answer to each query
for (int i = 0; i < N; i++) {
cout << ans[i] << endl;
}
}
Python3
# python program for above approach
# Function to find number of locations
# with rainfall more than K cms
def count(arr, Q, q, k):
ans = []
for i in range(0, q):
temp = 0
for j in range(Q[i][0], Q[i][1] + 1):
if (arr[j] >= k):
temp += 1
ans.append(temp)
return ans
# Function to find aggregate array
def aggregateArray(arr, n):
# To store the maximum location
m = 0
for i in range(0, n):
m = max(m, arr[i][1])
# Array to store the aggregate values
agg = [0 for _ in range(m + 1)]
for i in range(0, n):
for j in range(arr[i][0], arr[i][1] + 1):
agg[j] += arr[i][2]
return agg
# Driver Code
if __name__ == "__main__":
N = 4
arr = [
[1, 3, 5], [2, 8, 3],
[5, 8, 2], [7, 9, 6]
]
# Storing aggregate array
agg = aggregateArray(arr, N)
Q = 4
queries = [[1, 5], [5, 9],
[2, 9], [1, 9]]
K = 5
ans = count(agg, queries, Q, K)
# Printing answer to each query
for i in range(0, N):
print(ans[i])
# This code is contributed by rakeshsahni
Javascript
C++
// C++ program for above approach
#include
using namespace std;
// Comparator function to sort
// the array in specific order
static bool comp(vector a, vector b)
{
return (a[1] > b[1]);
}
// Function to find number of locations
// with rainfall more than K cms
vector count(vector arr, vector > Q,
int q, int k)
{
// Prefix sum array,
// of count of locations having
// rainfall greater than k cms
int n = arr.size();
vector arrPre(n);
if (arr[0] >= k)
arrPre[0] = 1;
else
arrPre[0] = 0;
for (int i = 1; i < n; i++) {
if (arr[i] >= k)
arrPre[i] = arrPre[i - 1] + 1;
else
arrPre[i] = arrPre[i - 1];
}
// evaluating the queries
vector ans;
for (int i = 0; i < q; i++) {
ans.push_back(arrPre[Q[i][1]]
- arrPre[Q[i][0] - 1]);
}
return ans;
}
// Function to find aggregate array
vector aggregateArray(vector > N, int n)
{
// To store the maximum location
int m = 0;
for (int i = 0; i < n; i++)
m = max(m, N[i][1]);
// Array to store rainfall
// of m locations sorting
// input array based on end time,
// in descending order
vector arr(m + 1);
sort(N.begin(), N.end(), comp);
// To store start locn and
// rainfall corresponding to it
unordered_map start;
int overlap = 0;
for (int i = 0; i < n; i++) {
// If two inputs have same end time,
// we need to reposition them
if (m < N[i][1])
m++;
else
// Fill m with overlap,
// till we reach current end location,
// and keep checking if we've crossed
// start time of previously recorded data
// and decrement overlap(map)
while (m > 0 && m != N[i][1])
overlap -= start[m], arr[m--] = overlap;
// To check if start time is crossed
// of previously recorded data
// and decrement overlap(map)
overlap -= start[m];
// Input data + previous recorded data
arr[m] = overlap + N[i][2];
// updating overlap with current data
overlap += N[i][2];
// storing start location with
// corresponding rainfall data
start[N[i][0] - 1] = N[i][2];
// update m
m--;
}
while (m >= N[n - 1][0])
// fill out the left out indexes
overlap -= start[m], arr[m--] = overlap;
return arr;
}
// Driver Code
int main()
{
int N = 4;
vector > arr = {
{ 1, 3, 5 }, { 2, 8, 3 }, { 5, 8, 2 }, { 7, 9, 6 }
};
vector agg = aggregateArray(arr, N);
int Q = 4;
vector > queries
= { { 1, 5 }, { 5, 9 }, { 2, 9 }, { 1, 9 } };
int K = 5;
vector ans = count(agg, queries, Q, K);
// Printing answer to each query
for (int i = 0; i < N; i++) {
cout << ans[i] << endl;
}
}
Python3
# Python program for above approach
# Function to find number of locations
# with rainfall more than K cms
from functools import cmp_to_key
def mycmp(a, b):
return b[1] - a[1]
def count(arr, Q, q, k):
# Prefix sum array,
# of count of locations having
# rainfall greater than k cms
n = len(arr)
arrPre = [0 for i in range(n)]
if (arr[0] >= k):
arrPre[0] = 1
else:
arrPre[0] = 0
for i in range(1,n):
if (arr[i] >= k):
arrPre[i] = arrPre[i - 1] + 1
else:
arrPre[i] = arrPre[i - 1]
# evaluating the queries
ans = []
for i in range(q):
ans.append(arrPre[Q[i][1]] - arrPre[Q[i][0] - 1])
return ans
# Function to find aggregate array
def aggregateArray(N, n):
# To store the maximum location
m = 0
for i in range(n):
m = max(m, N[i][1])
# Array to store rainfall
# of m locations sorting
# input array based on end time,
# in descending order
arr = [0 for i in range(m+1)]
N.sort(key = cmp_to_key(mycmp))
# To store start locn and
# rainfall corresponding to it
start = {}
overlap = 0
for i in range(n):
# If two inputs have same end time,
# we need to reposition them
if (m < N[i][1]):
m += 1
else:
# Fill m with overlap,
# till we reach current end location,
# and keep checking if we've crossed
# start time of previously recorded data
# and decreament overlap(map)
while (m > 0 and m != N[i][1]):
overlap -= start[m] if m in start else 0
arr[m] = overlap
m -= 1
# To check if start time is crossed
# of previously recorded data
# and decreament overlap(map)
overlap -= start[m] if m in start else 0
# Input data + previous recorded data
arr[m] = overlap + N[i][2]
# updating overlap with current data
overlap += N[i][2]
# storing start location with
# corresponding rainfall data
start[N[i][0] - 1] = N[i][2]
# update m
m -= 1
while (m >= N[n - 1][0]):
# fill out the left out indexes
overlap -= start[m] if m in start else 0
arr[m] = overlap
m -= 1
return arr
# Driver Code
N = 4
arr = [
[ 1, 3, 5 ], [ 2, 8, 3 ],
[ 5, 8, 2 ], [ 7, 9, 6 ]
]
agg = aggregateArray(arr, N)
Q = 4
queries = [ [ 1, 5 ], [ 5, 9 ],
[ 2, 9 ], [ 1, 9 ] ]
K = 5
ans = count(agg, queries, Q, K)
# Printing answer to each query
for i in range(N):
print(ans[i])
# This code is contributed by shinjanpatra
Javascript
Python3
# Python3 program for above approach
# Function to find number of locations with rainfall more than K cms
def count(arr, Q, q, k):
n = len(arr)
# prefix sum array
prefix = [0 for _ in range(n)]
if arr[0] >= k:
prefix[0] = 1
else:
prefix[0] = 0
for i in range(1, n-1):
if arr[i] >= k:
prefix[i] = prefix[i-1] + 1
else:
prefix[i] = prefix[i-1]
# evaluate the queries using prefix sum array
ans = []
for i in range(0, q):
start, end = Q[i][0]-1, Q[i][1]-1
# if start is the minimum location possible, store prefix[end]
if start == 0:
count = prefix[end]
else:
count = prefix[end] - prefix[start-1]
ans.append(count)
return ans
# Function to find aggregate array
def aggregateArray(arr, n):
# find maximum location possible
m = -1
for data in arr:
m = max(m, data[1])
# Array to store the aggregate values
agg = [0 for _ in range(m + 1)]
# update aggregate array at index start-1 and end locations
for start, end, val in arr:
agg[start-1] += val
agg[end] -= val
# iterate second time to fill the complete aggregate array
# currRain holds amount of rainfall till current index
currRain = 0
for i in range(m+1):
currRain += agg[i]
agg[i] = currRain
return agg
# Driver Code
if __name__ == "__main__":
N = 4
arr = [
[1, 3, 5], [2, 8, 3],
[5, 8, 2], [7, 9, 6]
]
# Storing aggregate array
agg = aggregateArray(arr, N)
Q = 4
queries = [[1, 5], [5, 9],
[2, 9], [1, 9]]
K = 5
ans = count(agg, queries, Q, K)
# Printing answer to each query
for i in range(0, N):
print(ans[i])
# This code is contributed by ultrainstinct
4
5
7
8
时间复杂度: O(max(O(N*M), O(Q*M)))。
辅助空间:O(M)。
其中N是输入数, Q是查询数, M是最大位置。
有效的方法:给定的问题可以通过使用加权作业调度方法和前缀和来解决。这个问题可以分两部分解决,形成聚合数组,然后应用前缀和来有效地回答查询。请按照以下步骤解决给定的问题。
- 根据结束位置对arr[][]进行排序。
- 使用地图数据结构存储起始位置和重叠计数。
- 对于每个结束位置,通过降雨数据 + 重叠更新聚合数组。
- 在越过起始位置后,使用 Hashmaps 减少重叠。
- 对于每个三元组,用开始时间更新 Hashmap。
- 遍历并填充数组中的重叠,直到到达下一个三元组的结束位置。
- 找到聚合数组后,使用前缀求和来查找每个查询的答案。
下面是上述方法的实现:
C++
// C++ program for above approach
#include
using namespace std;
// Comparator function to sort
// the array in specific order
static bool comp(vector a, vector b)
{
return (a[1] > b[1]);
}
// Function to find number of locations
// with rainfall more than K cms
vector count(vector arr, vector > Q,
int q, int k)
{
// Prefix sum array,
// of count of locations having
// rainfall greater than k cms
int n = arr.size();
vector arrPre(n);
if (arr[0] >= k)
arrPre[0] = 1;
else
arrPre[0] = 0;
for (int i = 1; i < n; i++) {
if (arr[i] >= k)
arrPre[i] = arrPre[i - 1] + 1;
else
arrPre[i] = arrPre[i - 1];
}
// evaluating the queries
vector ans;
for (int i = 0; i < q; i++) {
ans.push_back(arrPre[Q[i][1]]
- arrPre[Q[i][0] - 1]);
}
return ans;
}
// Function to find aggregate array
vector aggregateArray(vector > N, int n)
{
// To store the maximum location
int m = 0;
for (int i = 0; i < n; i++)
m = max(m, N[i][1]);
// Array to store rainfall
// of m locations sorting
// input array based on end time,
// in descending order
vector arr(m + 1);
sort(N.begin(), N.end(), comp);
// To store start locn and
// rainfall corresponding to it
unordered_map start;
int overlap = 0;
for (int i = 0; i < n; i++) {
// If two inputs have same end time,
// we need to reposition them
if (m < N[i][1])
m++;
else
// Fill m with overlap,
// till we reach current end location,
// and keep checking if we've crossed
// start time of previously recorded data
// and decrement overlap(map)
while (m > 0 && m != N[i][1])
overlap -= start[m], arr[m--] = overlap;
// To check if start time is crossed
// of previously recorded data
// and decrement overlap(map)
overlap -= start[m];
// Input data + previous recorded data
arr[m] = overlap + N[i][2];
// updating overlap with current data
overlap += N[i][2];
// storing start location with
// corresponding rainfall data
start[N[i][0] - 1] = N[i][2];
// update m
m--;
}
while (m >= N[n - 1][0])
// fill out the left out indexes
overlap -= start[m], arr[m--] = overlap;
return arr;
}
// Driver Code
int main()
{
int N = 4;
vector > arr = {
{ 1, 3, 5 }, { 2, 8, 3 }, { 5, 8, 2 }, { 7, 9, 6 }
};
vector agg = aggregateArray(arr, N);
int Q = 4;
vector > queries
= { { 1, 5 }, { 5, 9 }, { 2, 9 }, { 1, 9 } };
int K = 5;
vector ans = count(agg, queries, Q, K);
// Printing answer to each query
for (int i = 0; i < N; i++) {
cout << ans[i] << endl;
}
}
Python3
# Python program for above approach
# Function to find number of locations
# with rainfall more than K cms
from functools import cmp_to_key
def mycmp(a, b):
return b[1] - a[1]
def count(arr, Q, q, k):
# Prefix sum array,
# of count of locations having
# rainfall greater than k cms
n = len(arr)
arrPre = [0 for i in range(n)]
if (arr[0] >= k):
arrPre[0] = 1
else:
arrPre[0] = 0
for i in range(1,n):
if (arr[i] >= k):
arrPre[i] = arrPre[i - 1] + 1
else:
arrPre[i] = arrPre[i - 1]
# evaluating the queries
ans = []
for i in range(q):
ans.append(arrPre[Q[i][1]] - arrPre[Q[i][0] - 1])
return ans
# Function to find aggregate array
def aggregateArray(N, n):
# To store the maximum location
m = 0
for i in range(n):
m = max(m, N[i][1])
# Array to store rainfall
# of m locations sorting
# input array based on end time,
# in descending order
arr = [0 for i in range(m+1)]
N.sort(key = cmp_to_key(mycmp))
# To store start locn and
# rainfall corresponding to it
start = {}
overlap = 0
for i in range(n):
# If two inputs have same end time,
# we need to reposition them
if (m < N[i][1]):
m += 1
else:
# Fill m with overlap,
# till we reach current end location,
# and keep checking if we've crossed
# start time of previously recorded data
# and decreament overlap(map)
while (m > 0 and m != N[i][1]):
overlap -= start[m] if m in start else 0
arr[m] = overlap
m -= 1
# To check if start time is crossed
# of previously recorded data
# and decreament overlap(map)
overlap -= start[m] if m in start else 0
# Input data + previous recorded data
arr[m] = overlap + N[i][2]
# updating overlap with current data
overlap += N[i][2]
# storing start location with
# corresponding rainfall data
start[N[i][0] - 1] = N[i][2]
# update m
m -= 1
while (m >= N[n - 1][0]):
# fill out the left out indexes
overlap -= start[m] if m in start else 0
arr[m] = overlap
m -= 1
return arr
# Driver Code
N = 4
arr = [
[ 1, 3, 5 ], [ 2, 8, 3 ],
[ 5, 8, 2 ], [ 7, 9, 6 ]
]
agg = aggregateArray(arr, N)
Q = 4
queries = [ [ 1, 5 ], [ 5, 9 ],
[ 2, 9 ], [ 1, 9 ] ]
K = 5
ans = count(agg, queries, Q, K)
# Printing answer to each query
for i in range(N):
print(ans[i])
# This code is contributed by shinjanpatra
Javascript
4
5
7
8
时间复杂度: O(max(NlogN, M))。
辅助空间: O(M)。
其中 N 是输入数,M 是最大位置。
高效方法2 :在上述方法中,我们首先根据结束时间对数组进行排序,然后计算需要O(NLogN)时间的聚合数组。我们可以通过如下计算聚合数组来改进这个时间:
让聚合数组为agg[] 。
我们首先迭代每个降雨数据。对于每个数据( start 、 end和val ),将val添加到agg[start]并从agg[end+1]中减去val ,因为降雨从位置 start 开始并持续到 end(包括)。
然后,我们对agg数组进行第二次迭代并跟踪当前降雨量currRain (初始化为 0) 通过将agg[index]的值添加到其中并将agg[index]更新为currRain 。
创建聚合数组后,使用前缀 sum来查找每个查询的答案。
下面是上述方法的实现:
Python3
# Python3 program for above approach
# Function to find number of locations with rainfall more than K cms
def count(arr, Q, q, k):
n = len(arr)
# prefix sum array
prefix = [0 for _ in range(n)]
if arr[0] >= k:
prefix[0] = 1
else:
prefix[0] = 0
for i in range(1, n-1):
if arr[i] >= k:
prefix[i] = prefix[i-1] + 1
else:
prefix[i] = prefix[i-1]
# evaluate the queries using prefix sum array
ans = []
for i in range(0, q):
start, end = Q[i][0]-1, Q[i][1]-1
# if start is the minimum location possible, store prefix[end]
if start == 0:
count = prefix[end]
else:
count = prefix[end] - prefix[start-1]
ans.append(count)
return ans
# Function to find aggregate array
def aggregateArray(arr, n):
# find maximum location possible
m = -1
for data in arr:
m = max(m, data[1])
# Array to store the aggregate values
agg = [0 for _ in range(m + 1)]
# update aggregate array at index start-1 and end locations
for start, end, val in arr:
agg[start-1] += val
agg[end] -= val
# iterate second time to fill the complete aggregate array
# currRain holds amount of rainfall till current index
currRain = 0
for i in range(m+1):
currRain += agg[i]
agg[i] = currRain
return agg
# Driver Code
if __name__ == "__main__":
N = 4
arr = [
[1, 3, 5], [2, 8, 3],
[5, 8, 2], [7, 9, 6]
]
# Storing aggregate array
agg = aggregateArray(arr, N)
Q = 4
queries = [[1, 5], [5, 9],
[2, 9], [1, 9]]
K = 5
ans = count(agg, queries, Q, K)
# Printing answer to each query
for i in range(0, N):
print(ans[i])
# This code is contributed by ultrainstinct
4
5
7
8
时间复杂度: O(M)。
辅助空间: O(M)。
其中 M 是最大位置。