📌  相关文章
📜  Q查询后数组中形成的所有段中的最大段总和

📅  最后修改于: 2022-05-13 01:56:09.611000             🧑  作者: Mango

Q查询后数组中形成的所有段中的最大段总和

给定两个数组arr[] (基于 1 的索引)queries[] ,由N个整数组成,并且queries[]包含前N个自然数的排列,任务是对数组执行查询并找到最大和在每个查询查询[ i]中删除索引查询[i]处的数组元素并将该段分为2个段的所有段中的段。

例子:

方法:给定的问题可以通过使用不相交集联合数据结构来解决。想法是将所有查询存储在一个数组中,最初,所有元素都在不同的集合中,以相反的顺序处理查询,对于每个查询,使用查找操作对当前元素及其左右元素进行联合操作,并行跟踪最大元素,然后将其存储在数组中,然后以相反的顺序打印数组元素。请按照以下步骤解决问题:

  • 初始化向量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的值设置为maxAnssetSum[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)