Q查询后数组中形成的所有段中的最大段总和
给定两个数组arr[] (基于 1 的索引)和queries[] ,由N个整数组成,并且queries[]包含前N个自然数的排列,任务是对数组执行查询并找到最大和在每个查询查询[ i]中删除索引查询[i]处的数组元素并将该段分为2个段的所有段中的段。
例子:
Input: arr[] = {1, 3, 2, 5}, queries[] = {3, 4, 1, 2}
Output: 5 4 3 0
Explanation:
Following are the queries performed:
- Query 1: Remove the element at index 3 break the current array into {1, 3}, {5}. The maximum sum among all segments is 5.
- Query 2: Remove the element at index 4 break the current array into {1, 3} {}. The maximum sum among all segments is 4.
- Query 3: Remove the element at index 1 break the current array into {1}, {}. The maximum sum among all segments is 1.
- Query 4: Remove the element at index 2 break the current array into {}, {}. The maximum sum among all segments is 0.
Input: arr[] = {1, 2, 3, 4, 5}, queries[] = {4, 2, 3, 5, 1}
Output: 6 5 5 1 0
方法:给定的问题可以通过使用不相交集联合数据结构来解决。想法是将所有查询存储在一个数组中,最初,所有元素都在不同的集合中,以相反的顺序处理查询,对于每个查询,使用查找操作对当前元素及其左右元素进行联合操作,并行跟踪最大元素,然后将其存储在数组中,然后以相反的顺序打印数组元素。请按照以下步骤解决问题:
- 初始化向量parent(N + 1) 、 rank(N + 1, 0) 、 setSum(N + 1, 0)和currMax 。
- 使用变量i迭代范围[1, N+1)并将parent[i]的值设置为-1并将setSum[i]的值设置为arr[i – 1] 。
- 将值0推入向量currMax[]因为在最后一次查询之后答案将是0 。
- 使用变量i以相反的顺序迭代范围[N – 1, 0]并执行以下步骤:
- 如果parent[queries[ I ]]为-1 ,则将其设置为queries[i] 。
- 如果queries[i] – 1 >= 0 && parent[queries[i] – 1] != -1 ,则调用函数操作union(parent, rank, setSum, queries[ I ], queries[I]-1) .
- 如果queries[i] + 1 <= N && parent[queries[i] + 1] != -1,则调用函数运算union(parent, rank, setSum, queries[ I ], queries[I]+1) .
- 将maxAns的值设置为maxAns或setSum[queries[ I ]]的最大值,并将maxAns的值推入向量currMax[] 。
- 反转向量currMax[]并打印它的值作为答案。
下面是上述算法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Stores the maximum integer of the sets
// for each query
int maxAns = INT_MIN;
// Function to perform the find operation
// of disjoint set union
int Find(vector& parent, int a)
{
return parent[a]
= (parent[a] == a)
? a
: (Find(
parent, parent[a]));
}
// Function to perform the Union operation
// of disjoint set union
void Union(vector& parent, vector& rank,
vector& setSum, int a, int b)
{
// Find the parent of a and b
a = Find(parent, a);
b = Find(parent, b);
if (a == b)
return;
if (rank[a] > rank[b])
rank[a]++;
if (rank[b] > rank[a])
swap(a, b);
// Update the parent
parent[b] = a;
// Update the sum of set a
setSum[a] += setSum[b];
}
// Function to find the maximum element
// from the sets after each operation
void maxValues(vector arr,
vector queries, int N)
{
// Stores the parent elements of
// the sets
vector parent(N + 1);
// Stores the rank of the sets
vector rank(N + 1, 0);
// Stores the sum of the sets
vector setSum(N + 1, 0);
// Stores the maximum element for
// each query
vector currMax;
for (int i = 1; i < N + 1; i++) {
// Initially set is empty
parent[i] = -1;
// Update the sum as the
// current element
setSum[i] = arr[i - 1];
}
// After the last query set will
// be empty and sum will be 0
currMax.push_back(0);
for (int i = N - 1; i > 0; i--) {
// Check if the current element
// is not in any set then make
// parent as current element
// of the queries
if (parent[queries[i]] == -1) {
parent[queries[i]] = queries[i];
}
// Check left side of the queries[i]
// is not added in any set
if (queries[i] - 1 >= 0
&& parent[queries[i] - 1] != -1) {
// Add the queries[i] and the
// queries[i]-1 in one set
Union(parent, rank, setSum,
queries[i],
queries[i] - 1);
}
// Check right side of the queries[i]
// is not added in any set
if (queries[i] + 1 <= N
&& parent[queries[i] + 1] != -1) {
// Add queries[i] and the
// queries[i]+1 in one set
Union(parent, rank, setSum,
queries[i],
queries[i] + 1);
}
// Update the maxAns
maxAns = max(setSum[queries[i]],
maxAns);
// Push maxAns to the currMax
currMax.push_back(maxAns);
}
// Print currMax values in the
// reverse order
for (int i = currMax.size() - 1;
i >= 0; i--) {
cout << currMax[i] << " ";
}
}
// Driver Code
int main()
{
vector arr = { 1, 3, 2, 5 };
vector queries = { 3, 4, 1, 2 };
int N = arr.size();
maxValues(arr, queries, N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Stores the maximum integer of the sets
// for each query
static int maxAns = Integer.MIN_VALUE;
// Function to perform the find operation
// of disjoint set union
static int Find(int [] parent, int a)
{
return parent[a]
= (parent[a] == a)
? a
: (Find(
parent, parent[a]));
}
// Function to perform the Union operation
// of disjoint set union
static void Union(int [] parent, int [] rank,
int [] setSum, int a, int b)
{
// Find the parent of a and b
a = Find(parent, a);
b = Find(parent, b);
if (a == b)
return;
if (rank[a] > rank[b])
rank[a]++;
if (rank[b] > rank[a]) {
int x = a;
a = b;
b = x;
}
// Update the parent
parent[b] = a;
// Update the sum of set a
setSum[a] += setSum[b];
}
// Function to find the maximum element
// from the sets after each operation
static void maxValues(int [] arr,
int [] queries, int N)
{
// Stores the parent elements of
// the sets
int [] parent = new int[N + 1];
// Stores the rank of the sets
int [] rank = new int[N + 1];
// Stores the sum of the sets
int [] setSum = new int[N + 1];
// Stores the maximum element for
// each query
Vector currMax = new Vector();
for (int i = 1; i < N + 1; i++) {
// Initially set is empty
parent[i] = -1;
// Update the sum as the
// current element
setSum[i] = arr[i - 1];
}
// After the last query set will
// be empty and sum will be 0
currMax.add(0);
for (int i = N - 1; i > 0; i--) {
// Check if the current element
// is not in any set then make
// parent as current element
// of the queries
if (parent[queries[i]] == -1) {
parent[queries[i]] = queries[i];
}
// Check left side of the queries[i]
// is not added in any set
if (queries[i] - 1 >= 0
&& parent[queries[i] - 1] != -1) {
// Add the queries[i] and the
// queries[i]-1 in one set
Union(parent, rank, setSum,
queries[i],
queries[i] - 1);
}
// Check right side of the queries[i]
// is not added in any set
if (queries[i] + 1 <= N
&& parent[queries[i] + 1] != -1) {
// Add queries[i] and the
// queries[i]+1 in one set
Union(parent, rank, setSum,
queries[i],
queries[i] + 1);
}
// Update the maxAns
maxAns = Math.max(setSum[queries[i]],
maxAns);
// Push maxAns to the currMax
currMax.add(maxAns);
}
// Print currMax values in the
// reverse order
for (int i = currMax.size() - 1;
i >= 0; i--) {
System.out.print(currMax.get(i)+ " ");
}
}
// Driver Code
public static void main(String[] args)
{
int [] arr = { 1, 3, 2, 5 };
int [] queries = { 3, 4, 1, 2 };
int N = arr.length;
maxValues(arr, queries, N);
}
}
// This code is contributed by shikhasingrajput
Python3
# Python 3 program for the above approach
import sys
# Stores the maximum integer of the sets
# for each query
maxAns = -sys.maxsize - 1
# Function to perform the find operation
# of disjoint set union
def Find(parent, a):
if(parent[a] == a):
return a
return Find(parent, parent[a])
# Function to perform the Union operation
# of disjoint set union
def Union(parent, rank,
setSum, a, b):
# Find the parent of a and b
a = Find(parent, a)
b = Find(parent, b)
if (a == b):
return
if (rank[a] > rank[b]):
rank[a] += 1
if (rank[b] > rank[a]):
swap(a, b)
# Update the parent
parent[b] = a
# Update the sum of set a
setSum[a] += setSum[b]
# Function to find the maximum element
# from the sets after each operation
def maxValues(arr,
queries, N):
global maxAns
# Stores the parent elements of
# the sets
parent = [0]*(N + 1)
# Stores the rank of the sets
rank = [0]*(N + 1)
# Stores the sum of the sets
setSum = [0]*(N + 1)
# Stores the maximum element for
# each query
currMax = []
for i in range(1, N + 1):
# Initially set is empty
parent[i] = -1
# Update the sum as the
# current element
setSum[i] = arr[i - 1]
# After the last query set will
# be empty and sum will be 0
currMax.append(0)
for i in range(N - 1, 0, -1):
# Check if the current element
# is not in any set then make
# parent as current element
# of the queries
if (parent[queries[i]] == -1):
parent[queries[i]] = queries[i]
# Check left side of the queries[i]
# is not added in any set
if (queries[i] - 1 >= 0
and parent[queries[i] - 1] != -1):
# Add the queries[i] and the
# queries[i]-1 in one set
Union(parent, rank, setSum,
queries[i],
queries[i] - 1)
# Check right side of the queries[i]
# is not added in any set
if (queries[i] + 1 <= N
and parent[queries[i] + 1] != -1):
# Add queries[i] and the
# queries[i]+1 in one set
Union(parent, rank, setSum,
queries[i],
queries[i] + 1)
# Update the maxAns
maxAns = max(setSum[queries[i]], maxAns)
# Push maxAns to the currMax
currMax.append(maxAns)
# Print currMax values in the
# reverse order
for i in range(len(currMax) - 1, -1, -1):
print(currMax[i], end=" ")
# Driver Code
if __name__ == "__main__":
arr = [1, 3, 2, 5]
queries = [3, 4, 1, 2]
N = len(arr)
maxValues(arr, queries, N)
# This code is contributed by ukasp.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
public class GFG{
// Stores the maximum integer of the sets
// for each query
static int maxAns = int.MinValue;
// Function to perform the find operation
// of disjoint set union
static int Find(int [] parent, int a)
{
return parent[a]
= (parent[a] == a)
? a
: (Find(
parent, parent[a]));
}
// Function to perform the Union operation
// of disjoint set union
static void Union(int [] parent, int [] rank,
int [] setSum, int a, int b)
{
// Find the parent of a and b
a = Find(parent, a);
b = Find(parent, b);
if (a == b)
return;
if (rank[a] > rank[b])
rank[a]++;
if (rank[b] > rank[a]) {
int x = a;
a = b;
b = x;
}
// Update the parent
parent[b] = a;
// Update the sum of set a
setSum[a] += setSum[b];
}
// Function to find the maximum element
// from the sets after each operation
static void maxValues(int [] arr,
int [] queries, int N)
{
// Stores the parent elements of
// the sets
int [] parent = new int[N + 1];
// Stores the rank of the sets
int [] rank = new int[N + 1];
// Stores the sum of the sets
int [] setSum = new int[N + 1];
// Stores the maximum element for
// each query
List currMax = new List();
for (int i = 1; i < N + 1; i++) {
// Initially set is empty
parent[i] = -1;
// Update the sum as the
// current element
setSum[i] = arr[i - 1];
}
// After the last query set will
// be empty and sum will be 0
currMax.Add(0);
for (int i = N - 1; i > 0; i--) {
// Check if the current element
// is not in any set then make
// parent as current element
// of the queries
if (parent[queries[i]] == -1) {
parent[queries[i]] = queries[i];
}
// Check left side of the queries[i]
// is not added in any set
if (queries[i] - 1 >= 0
&& parent[queries[i] - 1] != -1) {
// Add the queries[i] and the
// queries[i]-1 in one set
Union(parent, rank, setSum,
queries[i],
queries[i] - 1);
}
// Check right side of the queries[i]
// is not added in any set
if (queries[i] + 1 <= N
&& parent[queries[i] + 1] != -1) {
// Add queries[i] and the
// queries[i]+1 in one set
Union(parent, rank, setSum,
queries[i],
queries[i] + 1);
}
// Update the maxAns
maxAns = Math.Max(setSum[queries[i]],
maxAns);
// Push maxAns to the currMax
currMax.Add(maxAns);
}
// Print currMax values in the
// reverse order
for (int i = currMax.Count - 1;
i >= 0; i--) {
Console.Write(currMax[i]+ " ");
}
}
// Driver Code
public static void Main(String[] args)
{
int [] arr = { 1, 3, 2, 5 };
int [] queries = { 3, 4, 1, 2 };
int N = arr.Length;
maxValues(arr, queries, N);
}
}
// This code is contributed by shikhasingrajput
Javascript
输出:
5 4 3 0
时间复杂度: O(N*log N)
辅助空间: O(N)