📌  相关文章
📜  查询以查找仅由1组成的最长子数组的长度

📅  最后修改于: 2021-05-19 19:20:24             🧑  作者: Mango

给定大小为N的二进制数组arr []和包含以下两种类型的K个查询的2D数组Q [] []

  • 1:打印最长的子数组的长度,仅由1 s组成。
  • 2 X:将元素翻转到第X索引(从1开始的索引),即,如果当前元素为‘0’ ,则将该元素更改为‘1 ,反之亦然。

例子:

天真的方法:解决问题的最简单方法是遍历每个查询的数组arr []并执行给定的操作。

下面是上述方法的实现:

C++
// C++ Program for the above approach
 
#include 
using namespace std;
 
// Function to calculate the longest subarray
// consisting of 1s only
int longestsubarray(int a[], int N)
{
    // Stores the maximum length of
    // subarray containing 1s only
    int maxlength = 0, sum = 0;
 
    // Traverse the array
    for (int i = 0; i < N; i++) {
 
        // If current element is '1'
        if (a[i] == 1) {
 
            // Increment length
            sum++;
        }
 
        // Otherwise
        else {
 
            // Reset length
            sum = 0;
        }
 
        // Update maximum subarray length
        maxlength = max(maxlength, sum);
    }
    return maxlength;
}
 
// Function to perform given queries
void solveQueries(int arr[], int n,
                  vector > Q, int k)
{
 
    // Stores count of queries
    int cntQuery = Q.size();
 
    // Traverse each query
    for (int i = 0; i < cntQuery; i++) {
 
        if (Q[i][0] == 1) {
            cout << longestsubarray(arr, n) << " ";
        }
        else {
            // Flip the character
            arr[Q[i][1] - 1] ^= 1;
        }
    }
}
 
// Driver Code
int main()
{
    // Size of array
    int N = 10;
 
    // Given array
    int arr[] = { 1, 1, 0, 1, 1,
                  1, 0, 0, 1, 1 };
 
    // Given queries
    vector > Q = { { 1 }, { 2, 3 }, { 1 } };
 
    // Number of queries
    int K = 3;
 
    solveQueries(arr, N, Q, K);
}


Java
// Java Program for the above approach
import java.util.*;
public class Main
{
  // Function to calculate the longest subarray
  // consisting of 1s only
  static int longestsubarray(int a[], int N)
  {
 
    // Stores the maximum length of
    // subarray containing 1s only
    int maxlength = 0, sum = 0;
 
    // Traverse the array
    for (int i = 0; i < N; i++)
    {
 
      // If current element is '1'
      if (a[i] == 1)
      {
 
        // Increment length
        sum++;
      }
 
      // Otherwise
      else
      {
 
        // Reset length
        sum = 0;
      }
 
      // Update maximum subarray length
      maxlength = Math.max(maxlength, sum);
    }
    return maxlength;
  }
 
  // Function to perform given queries
  static void solveQueries(int arr[], int n,
                           Vector> Q, int k)
  {
 
    // Stores count of queries
    int cntQuery = Q.size();
 
    // Traverse each query
    for (int i = 0; i < cntQuery; i++)
    {
 
      if (Q.get(i).get(0) == 1)
      {
        System.out.print(longestsubarray(arr, n) + " ");
      }
      else
      {
 
        // Flip the character
        arr[Q.get(i).get(1) - 1] ^= 1;
      }
    }
  }
 
  public static void main(String[] args) {
    // Size of array
    int N = 10;
 
    // Given array
    int arr[] = { 1, 1, 0, 1, 1,
                 1, 0, 0, 1, 1 };
 
    // Given queries
    Vector> Q = new Vector>();
    Vector v1 = new Vector();
    Vector v2 = new Vector();
    Vector v3 = new Vector();
    v1.add(1);
    v2.add(2);
    v2.add(3);
    v3.add(1);
    Q.add(v1);
    Q.add(v2);
    Q.add(v3);
 
    // Number of queries
    int K = 3;
 
    solveQueries(arr, N, Q, K);
  }
}
 
// This code is contributed by divyesh072019


Python3
# Python Program for the above approach
 
# Function to calculate the longest subarray
# consisting of 1s only
def longestsubarray(a, N) :
     
    # Stores the maximum length of
    # subarray containing 1s only
    maxlength = 0
    sum = 0
 
    # Traverse the array
    for i in range(N):
 
        # If current element is '1'
        if (a[i] == 1) :
 
            # Increment length
            sum += 1
             
        # Otherwise
        else :
 
            # Reset length
            sum = 0
         
 
        # Update maximum subarray length
        maxlength = max(maxlength, sum)   
    return maxlength
 
# Function to perform given queries
def solveQueries(arr, n, Q, k) :
 
    # Stores count of queries
    cntQuery = len(Q)
 
    # Traverse each query
    for i in range(cntQuery):
 
        if (Q[i][0] == 1) :
            print(longestsubarray(arr, n), end = " ")
         
        else :
            # Flip the character
            arr[Q[i][1] - 1] ^= 1
         
# Driver Code
 
# Size of array
N = 10
 
# Given array
arr = [ 1, 1, 0, 1, 1,
        1, 0, 0, 1, 1]
 
# Given queries
Q = [[1], [ 2, 3 ], [1]] 
 
# Number of queries
K = 3
solveQueries(arr, N, Q, K)
 
# This code is contributed by sanjoy_62


C#
// C# Program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
     
    // Function to calculate the longest subarray
    // consisting of 1s only
    static int longestsubarray(int[] a, int N)
    {
       
        // Stores the maximum length of
        // subarray containing 1s only
        int maxlength = 0, sum = 0;
       
        // Traverse the array
        for (int i = 0; i < N; i++)
        {
       
            // If current element is '1'
            if (a[i] == 1)
            {
       
                // Increment length
                sum++;
            }
       
            // Otherwise
            else
            {
       
                // Reset length
                sum = 0;
            }
       
            // Update maximum subarray length
            maxlength = Math.Max(maxlength, sum);
        }
        return maxlength;
    }
       
    // Function to perform given queries
    static void solveQueries(int[] arr, int n,
                      List> Q, int k)
    {
       
        // Stores count of queries
        int cntQuery = Q.Count;
       
        // Traverse each query
        for (int i = 0; i < cntQuery; i++)
        {
       
            if (Q[i][0] == 1)
            {
                Console.Write(longestsubarray(arr, n) + " ");
            }
            else
            {
               
                // Flip the character
                arr[Q[i][1] - 1] ^= 1;
            }
        }
    }
 
  // Driver code
  static void Main()
  {
       
    // Size of array
    int N = 10;
   
    // Given array
    int[] arr = { 1, 1, 0, 1, 1,
                  1, 0, 0, 1, 1 };
   
    // Given queries
    List> Q = new List>();
    Q.Add(new List { 1 });
    Q.Add(new List { 2, 3 });
    Q.Add(new List { 1 });
   
    // Number of queries
    int K = 3;
   
    solveQueries(arr, N, Q, K);
  }
}
 
// This code is contributed by divyeshrabadiya07


C++
// C++ Program for the above approach
 
#include 
using namespace std;
 
#define INF 1000000
 
// Arrays to store prefix sums, suffix
// and MAX's node respectively
int pref[500005];
int suf[500005];
int MAX[500005];
 
// Function to construct Segment Tree
void build(int a[], int tl, int tr, int v)
{
    if (tl == tr) {
 
        // MAX array for node MAX
        MAX[v] = a[tl];
 
        // Array for prefix sum node
        pref[v] = a[tl];
        // Array for suffix sum node
        suf[v] = a[tl];
    }
    else {
        int tm = (tl + tr) / 2;
        build(a, tl, tm, v * 2);
        build(a, tm + 1, tr, v * 2 + 1);
 
        // Calculate MAX node
        MAX[v] = max(MAX[v * 2],
                     max(MAX[v * 2 + 1],
                         suf[v * 2] + pref[v * 2 + 1]));
 
        pref[v] = max(pref[v * 2],
                      pref[2 * v]
                          + (pref[2 * v] == tm - tl + 1)
                                * pref[v * 2 + 1]);
 
        suf[v] = max(
            suf[v * 2 + 1],
            suf[2 * v + 1]
                + suf[v * 2] * (suf[2 * v + 1] == tr - tm));
    }
}
 
// Function to update Segment Tree
void update(int a[], int pos, int tl,
            int tr, int v)
{
    if (tl > pos || tr < pos) {
        return;
    }
 
    // Update at position
    if (tl == tr && tl == pos) {
 
        MAX[v] = a[pos];
        pref[v] = a[pos];
        suf[v] = a[pos];
    }
    else {
 
        // Update sums from bottom to the
        // top of Segment Tree
        int tm = (tl + tr) / 2;
        update(a, pos, tl, tm, v * 2);
        update(a, pos, tm + 1, tr, v * 2 + 1);
 
        // Update MAX tree
        MAX[v] = max(MAX[v * 2],
                     max(MAX[v * 2 + 1],
                         suf[v * 2] + pref[v * 2 + 1]));
        // Update pref tree
        pref[v] = max(pref[v * 2],
                      pref[2 * v]
                          + (pref[2 * v] == tm - tl + 1)
                                * pref[v * 2 + 1]);
        // Update suf tree
        suf[v] = max(suf[v * 2 + 1],
                     suf[2 * v + 1]
                         + (suf[2 * v + 1] == tr - tm)
                               * suf[v * 2]);
    }
}
 
// Function to perform given queries
void solveQueries(int arr[], int n,
                  vector > Q, int k)
{
    // Stores count of queries
    int cntQuery = Q.size();
 
    build(arr, 0, n - 1, 1);
 
    // Traverse each query
    for (int i = 0; i < cntQuery; i++) {
        if (Q[i][0] == 1) {
 
            // Print longest length of subarray in [1, N]
            cout << MAX[1] << " ";
        }
 
        else {
 
            // Flip the character
            arr[Q[i][1] - 1] ^= 1;
            update(arr, Q[i][1] - 1, 0, n - 1, 1);
        }
    }
}
 
// Driver Code
int main()
{
    // Size of array
    int N = 10;
 
    // Given array
    int arr[] = { 1, 1, 0, 1, 1,
                  1, 0, 0, 1, 1 };
 
    // Given queries
    vector > Q = { { 1 }, { 2, 3 }, { 1 } };
 
    // Number of queries
    int K = 3;
 
    solveQueries(arr, N, Q, K);
}


Java
// Java Program for the above approach
import java.util.*;
class GFG
{
static final int INF = 1000000;
 
// Arrays to store prefix sums, suffix
// and MAX's node respectively
static int []pref = new int[500005];
static int []suf = new int[500005];
static int []MAX = new int[500005];
 
// Function to conSegment Tree
static void build(int a[], int tl, int tr, int v)
{
    if (tl == tr) {
 
        // MAX array for node MAX
        MAX[v] = a[tl];
 
        // Array for prefix sum node
        pref[v] = a[tl];
        // Array for suffix sum node
        suf[v] = a[tl];
    }
    else {
        int tm = (tl + tr) / 2;
        build(a, tl, tm, v * 2);
        build(a, tm + 1, tr, v * 2 + 1);
 
        // Calculate MAX node
        MAX[v] = Math.max(MAX[v * 2],
                     Math.max(MAX[v * 2 + 1],
                         suf[v * 2] + pref[v * 2 + 1]));
 
        pref[v] = Math.max(pref[v * 2],
                      pref[2 * v]
                          + (pref[2 * v] == (tm - tl + 1)?1:0)
                                * pref[v * 2 + 1]);
        suf[v] = Math.max(
            suf[v * 2 + 1],
            suf[2 * v + 1]
                + suf[v * 2] * (suf[2 * v + 1] == (tr - tm)?1:0));
    }
}
 
// Function to update Segment Tree
static void update(int a[], int pos, int tl,
            int tr, int v)
{
    if (tl > pos || tr < pos) {
        return;
    }
 
    // Update at position
    if (tl == tr && tl == pos)
    {
        MAX[v] = a[pos];
        pref[v] = a[pos];
        suf[v] = a[pos];
    }
    else {
 
        // Update sums from bottom to the
        // top of Segment Tree
        int tm = (tl + tr) / 2;
        update(a, pos, tl, tm, v * 2);
        update(a, pos, tm + 1, tr, v * 2 + 1);
 
        // Update MAX tree
        MAX[v] = Math.max(MAX[v * 2],
                     Math.max(MAX[v * 2 + 1],
                         suf[v * 2] + pref[v * 2 + 1]));
        // Update pref tree
        pref[v] = Math.max(pref[v * 2],
                      pref[2 * v]
                          + (pref[2 * v] == (tm - tl + 1)?1:0)
                                * pref[v * 2 + 1]);
        // Update suf tree
        suf[v] = Math.max(suf[v * 2 + 1],
                     suf[2 * v + 1]
                         + (suf[2 * v + 1] == (tr - tm)?1:0)
                               * suf[v * 2]);
    }
}
 
// Function to perform given queries
static void solveQueries(int arr[], int n,
                  int[][] Q, int k)
{
    // Stores count of queries
    int cntQuery = Q.length;
    build(arr, 0, n - 1, 1);
 
    // Traverse each query
    for (int i = 0; i < cntQuery; i++)
    {
        if (Q[i][0] == 1)
        {
 
            // Print longest length of subarray in [1, N]
            System.out.print(MAX[1]+ " ");
        }
 
        else
        {
 
            // Flip the character
            arr[Q[i][1] - 1] ^= 1;
            update(arr, Q[i][1] - 1, 0, n - 1, 1);
        }
    }
}
 
// Driver Code
public static void main(String[] args)
{
    // Size of array
    int N = 10;
 
    // Given array
    int arr[] = { 1, 1, 0, 1, 1,
                  1, 0, 0, 1, 1 };
 
    // Given queries
    int [][]Q = { { 1 }, { 2, 3 }, { 1 } };
 
    // Number of queries
    int K = 3;
 
    solveQueries(arr, N, Q, K);
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python 3 Program for the above approach
INF = 1000000
 
# Arrays to store prefix sums, suffix
# and MAX's node respectively
pref = [0 for i in range(500005)]
suf = [0 for i in range(500005)]
MAX = [0 for i in range(500005)]
 
# Function to construct Segment Tree
def build(a, tl,tr,v):
    global MAX
    global pref
    global suf
    if (tl == tr):
       
        # MAX array for node MAX
        MAX[v] = a[tl]
 
        # Array for prefix sum node
        pref[v] = a[tl]
         
        # Array for suffix sum node
        suf[v] = a[tl]
    else:
        tm = (tl + tr) // 2
        build(a, tl, tm, v * 2)
        build(a, tm + 1, tr, v * 2 + 1)
 
        # Calculate MAX node
        MAX[v] = max(MAX[v * 2], max(MAX[v * 2 + 1], suf[v * 2] + pref[v * 2 + 1]))
 
        pref[v] = max(pref[v * 2], pref[2 * v] + (pref[2 * v] == tm - tl + 1)* pref[v * 2 + 1])
 
        suf[v] = max(suf[v * 2 + 1],suf[2 * v + 1]+suf[v * 2] * (suf[2 * v + 1] == tr - tm))
 
# Function to update Segment Tree
def update(a,pos,tl,tr,v):
    global pref
    global suf
    global MAX
    if (tl > pos or tr < pos):
        return
 
    # Update at position
    if (tl == tr and tl == pos):
        MAX[v] = a[pos]
        pref[v] = a[pos]
        suf[v] = a[pos]
    else:
        # Update sums from bottom to the
        # top of Segment Tree
        tm = (tl + tr) // 2
        update(a, pos, tl, tm, v * 2)
        update(a, pos, tm + 1, tr, v * 2 + 1)
 
        # Update MAX tree
        MAX[v] = max(MAX[v * 2], max(MAX[v * 2 + 1], suf[v * 2] + pref[v * 2 + 1]))
         
        # Update pref tree
        pref[v] = max(pref[v * 2], pref[2 * v] + (pref[2 * v] == tm - tl + 1) * pref[v * 2 + 1])
         
        # Update suf tree
        suf[v] = max(suf[v * 2 + 1], suf[2 * v + 1] + (suf[2 * v + 1] == tr - tm) * suf[v * 2])
 
# Function to perform given queries
def solveQueries(arr, n, Q, k):
    global MAX
     
    # Stores count of queries
    cntQuery = len(Q)
    build(arr, 0, n - 1, 1)
 
    # Traverse each query
    for i in range(cntQuery):
        if (Q[i][0] == 1):
           
            # Print longest length of subarray in [1, N]
            print(MAX[1],end = " ")
 
        else:
            # Flip the character
            arr[Q[i][1] - 1] ^= 1
            update(arr, Q[i][1] - 1, 0, n - 1, 1)
 
# Driver Code
if __name__ == '__main__':
   
    # Size of array
    N = 10
     
    # Given array
    arr =  [1, 1, 0, 1, 1, 1, 0, 0, 1, 1]
     
    # Given queries
    Q =  [[1], [2, 3], [1]]
     
    # Number of queries
    K = 3
    solveQueries(arr, N, Q, K)
     
    # This code is contributed by SURENDRA_GANGWAR.


C#
// C# Program for the above approach
using System;
class GFG
{
   
static readonly int INF = 1000000;
 
// Arrays to store prefix sums, suffix
// and MAX's node respectively
static int []pref = new int[500005];
static int []suf = new int[500005];
static int []MAX = new int[500005];
 
// Function to conSegment Tree
static void build(int []a, int tl, int tr, int v)
{
    if (tl == tr)
    {
 
        // MAX array for node MAX
        MAX[v] = a[tl];
 
        // Array for prefix sum node
        pref[v] = a[tl];
       
        // Array for suffix sum node
        suf[v] = a[tl];
    }
    else
    {
        int tm = (tl + tr) / 2;
        build(a, tl, tm, v * 2);
        build(a, tm + 1, tr, v * 2 + 1);
 
        // Calculate MAX node
        MAX[v] = Math.Max(MAX[v * 2],
                     Math.Max(MAX[v * 2 + 1],
                         suf[v * 2] + pref[v * 2 + 1]));
        pref[v] = Math.Max(pref[v * 2],
                      pref[2 * v]
                          + (pref[2 * v] == (tm - tl + 1)?1:0)
                                * pref[v * 2 + 1]);
        suf[v] = Math.Max(
            suf[v * 2 + 1],
            suf[2 * v + 1]
                + suf[v * 2] * (suf[2 * v + 1] == (tr - tm)?1:0));
    }
}
 
// Function to update Segment Tree
static void update(int []a, int pos, int tl,
            int tr, int v)
{
    if (tl > pos || tr < pos)
    {
        return;
    }
 
    // Update at position
    if (tl == tr && tl == pos)
    {
        MAX[v] = a[pos];
        pref[v] = a[pos];
        suf[v] = a[pos];
    }
    else
    {
 
        // Update sums from bottom to the
        // top of Segment Tree
        int tm = (tl + tr) / 2;
        update(a, pos, tl, tm, v * 2);
        update(a, pos, tm + 1, tr, v * 2 + 1);
 
        // Update MAX tree
        MAX[v] = Math.Max(MAX[v * 2],
                     Math.Max(MAX[v * 2 + 1],
                         suf[v * 2] + pref[v * 2 + 1]));
         
      // Update pref tree
        pref[v] = Math.Max(pref[v * 2],
                      pref[2 * v]
                          + (pref[2 * v] == (tm - tl + 1)?1:0)
                                * pref[v * 2 + 1]);
         
      // Update suf tree
        suf[v] = Math.Max(suf[v * 2 + 1],
                     suf[2 * v + 1]
                         + (suf[2 * v + 1] == (tr - tm)?1:0)
                               * suf[v * 2]);
    }
}
 
// Function to perform given queries
static void solveQueries(int []arr, int n,
                  int[,] Q, int k)
{
   
    // Stores count of queries
    int cntQuery = Q.GetLength(0);
    build(arr, 0, n - 1, 1);
 
    // Traverse each query
    for (int i = 0; i < cntQuery; i++)
    {
        if (Q[i, 0] == 1)
        {
 
            // Print longest length of subarray in [1, N]
            Console.Write(MAX[1] + " ");
        }
 
        else
        {
 
            // Flip the character
            arr[Q[i, 1] - 1] ^= 1;
            update(arr, Q[i, 1] - 1, 0, n - 1, 1);
        }
    }
}
 
// Driver Code
public static void Main(String[] args)
{
   
    // Size of array
    int N = 10;
 
    // Given array
    int []arr = { 1, 1, 0, 1, 1,
                  1, 0, 0, 1, 1 };
 
    // Given queries
    int [,]Q = { { 1,0 }, { 2, 3 }, { 1,0 } };
 
    // Number of queries
    int K = 3;
    solveQueries(arr, N, Q, K);
}
}
 
// This code is contributed by 29AjayKumar


输出:
3 6

时间复杂度: (N * K)
辅助空间: O(N)

高效的方法:可以使用“段树”数据结构来优化上述方法。可以根据以下观察结果解决给定的问题:

请按照以下步骤解决问题:

  • 对于类型1的查询,打印段树的根节点MAX [1] ,该树包含最长的子数组长度,该子数组仅由[1,N]范围内的1组成
  • 对于类型2的查询,翻转给定位置并更新段树。

下面是上述方法的实现:

C++

// C++ Program for the above approach
 
#include 
using namespace std;
 
#define INF 1000000
 
// Arrays to store prefix sums, suffix
// and MAX's node respectively
int pref[500005];
int suf[500005];
int MAX[500005];
 
// Function to construct Segment Tree
void build(int a[], int tl, int tr, int v)
{
    if (tl == tr) {
 
        // MAX array for node MAX
        MAX[v] = a[tl];
 
        // Array for prefix sum node
        pref[v] = a[tl];
        // Array for suffix sum node
        suf[v] = a[tl];
    }
    else {
        int tm = (tl + tr) / 2;
        build(a, tl, tm, v * 2);
        build(a, tm + 1, tr, v * 2 + 1);
 
        // Calculate MAX node
        MAX[v] = max(MAX[v * 2],
                     max(MAX[v * 2 + 1],
                         suf[v * 2] + pref[v * 2 + 1]));
 
        pref[v] = max(pref[v * 2],
                      pref[2 * v]
                          + (pref[2 * v] == tm - tl + 1)
                                * pref[v * 2 + 1]);
 
        suf[v] = max(
            suf[v * 2 + 1],
            suf[2 * v + 1]
                + suf[v * 2] * (suf[2 * v + 1] == tr - tm));
    }
}
 
// Function to update Segment Tree
void update(int a[], int pos, int tl,
            int tr, int v)
{
    if (tl > pos || tr < pos) {
        return;
    }
 
    // Update at position
    if (tl == tr && tl == pos) {
 
        MAX[v] = a[pos];
        pref[v] = a[pos];
        suf[v] = a[pos];
    }
    else {
 
        // Update sums from bottom to the
        // top of Segment Tree
        int tm = (tl + tr) / 2;
        update(a, pos, tl, tm, v * 2);
        update(a, pos, tm + 1, tr, v * 2 + 1);
 
        // Update MAX tree
        MAX[v] = max(MAX[v * 2],
                     max(MAX[v * 2 + 1],
                         suf[v * 2] + pref[v * 2 + 1]));
        // Update pref tree
        pref[v] = max(pref[v * 2],
                      pref[2 * v]
                          + (pref[2 * v] == tm - tl + 1)
                                * pref[v * 2 + 1]);
        // Update suf tree
        suf[v] = max(suf[v * 2 + 1],
                     suf[2 * v + 1]
                         + (suf[2 * v + 1] == tr - tm)
                               * suf[v * 2]);
    }
}
 
// Function to perform given queries
void solveQueries(int arr[], int n,
                  vector > Q, int k)
{
    // Stores count of queries
    int cntQuery = Q.size();
 
    build(arr, 0, n - 1, 1);
 
    // Traverse each query
    for (int i = 0; i < cntQuery; i++) {
        if (Q[i][0] == 1) {
 
            // Print longest length of subarray in [1, N]
            cout << MAX[1] << " ";
        }
 
        else {
 
            // Flip the character
            arr[Q[i][1] - 1] ^= 1;
            update(arr, Q[i][1] - 1, 0, n - 1, 1);
        }
    }
}
 
// Driver Code
int main()
{
    // Size of array
    int N = 10;
 
    // Given array
    int arr[] = { 1, 1, 0, 1, 1,
                  1, 0, 0, 1, 1 };
 
    // Given queries
    vector > Q = { { 1 }, { 2, 3 }, { 1 } };
 
    // Number of queries
    int K = 3;
 
    solveQueries(arr, N, Q, K);
}

Java

// Java Program for the above approach
import java.util.*;
class GFG
{
static final int INF = 1000000;
 
// Arrays to store prefix sums, suffix
// and MAX's node respectively
static int []pref = new int[500005];
static int []suf = new int[500005];
static int []MAX = new int[500005];
 
// Function to conSegment Tree
static void build(int a[], int tl, int tr, int v)
{
    if (tl == tr) {
 
        // MAX array for node MAX
        MAX[v] = a[tl];
 
        // Array for prefix sum node
        pref[v] = a[tl];
        // Array for suffix sum node
        suf[v] = a[tl];
    }
    else {
        int tm = (tl + tr) / 2;
        build(a, tl, tm, v * 2);
        build(a, tm + 1, tr, v * 2 + 1);
 
        // Calculate MAX node
        MAX[v] = Math.max(MAX[v * 2],
                     Math.max(MAX[v * 2 + 1],
                         suf[v * 2] + pref[v * 2 + 1]));
 
        pref[v] = Math.max(pref[v * 2],
                      pref[2 * v]
                          + (pref[2 * v] == (tm - tl + 1)?1:0)
                                * pref[v * 2 + 1]);
        suf[v] = Math.max(
            suf[v * 2 + 1],
            suf[2 * v + 1]
                + suf[v * 2] * (suf[2 * v + 1] == (tr - tm)?1:0));
    }
}
 
// Function to update Segment Tree
static void update(int a[], int pos, int tl,
            int tr, int v)
{
    if (tl > pos || tr < pos) {
        return;
    }
 
    // Update at position
    if (tl == tr && tl == pos)
    {
        MAX[v] = a[pos];
        pref[v] = a[pos];
        suf[v] = a[pos];
    }
    else {
 
        // Update sums from bottom to the
        // top of Segment Tree
        int tm = (tl + tr) / 2;
        update(a, pos, tl, tm, v * 2);
        update(a, pos, tm + 1, tr, v * 2 + 1);
 
        // Update MAX tree
        MAX[v] = Math.max(MAX[v * 2],
                     Math.max(MAX[v * 2 + 1],
                         suf[v * 2] + pref[v * 2 + 1]));
        // Update pref tree
        pref[v] = Math.max(pref[v * 2],
                      pref[2 * v]
                          + (pref[2 * v] == (tm - tl + 1)?1:0)
                                * pref[v * 2 + 1]);
        // Update suf tree
        suf[v] = Math.max(suf[v * 2 + 1],
                     suf[2 * v + 1]
                         + (suf[2 * v + 1] == (tr - tm)?1:0)
                               * suf[v * 2]);
    }
}
 
// Function to perform given queries
static void solveQueries(int arr[], int n,
                  int[][] Q, int k)
{
    // Stores count of queries
    int cntQuery = Q.length;
    build(arr, 0, n - 1, 1);
 
    // Traverse each query
    for (int i = 0; i < cntQuery; i++)
    {
        if (Q[i][0] == 1)
        {
 
            // Print longest length of subarray in [1, N]
            System.out.print(MAX[1]+ " ");
        }
 
        else
        {
 
            // Flip the character
            arr[Q[i][1] - 1] ^= 1;
            update(arr, Q[i][1] - 1, 0, n - 1, 1);
        }
    }
}
 
// Driver Code
public static void main(String[] args)
{
    // Size of array
    int N = 10;
 
    // Given array
    int arr[] = { 1, 1, 0, 1, 1,
                  1, 0, 0, 1, 1 };
 
    // Given queries
    int [][]Q = { { 1 }, { 2, 3 }, { 1 } };
 
    // Number of queries
    int K = 3;
 
    solveQueries(arr, N, Q, K);
}
}
 
// This code is contributed by 29AjayKumar

Python3

# Python 3 Program for the above approach
INF = 1000000
 
# Arrays to store prefix sums, suffix
# and MAX's node respectively
pref = [0 for i in range(500005)]
suf = [0 for i in range(500005)]
MAX = [0 for i in range(500005)]
 
# Function to construct Segment Tree
def build(a, tl,tr,v):
    global MAX
    global pref
    global suf
    if (tl == tr):
       
        # MAX array for node MAX
        MAX[v] = a[tl]
 
        # Array for prefix sum node
        pref[v] = a[tl]
         
        # Array for suffix sum node
        suf[v] = a[tl]
    else:
        tm = (tl + tr) // 2
        build(a, tl, tm, v * 2)
        build(a, tm + 1, tr, v * 2 + 1)
 
        # Calculate MAX node
        MAX[v] = max(MAX[v * 2], max(MAX[v * 2 + 1], suf[v * 2] + pref[v * 2 + 1]))
 
        pref[v] = max(pref[v * 2], pref[2 * v] + (pref[2 * v] == tm - tl + 1)* pref[v * 2 + 1])
 
        suf[v] = max(suf[v * 2 + 1],suf[2 * v + 1]+suf[v * 2] * (suf[2 * v + 1] == tr - tm))
 
# Function to update Segment Tree
def update(a,pos,tl,tr,v):
    global pref
    global suf
    global MAX
    if (tl > pos or tr < pos):
        return
 
    # Update at position
    if (tl == tr and tl == pos):
        MAX[v] = a[pos]
        pref[v] = a[pos]
        suf[v] = a[pos]
    else:
        # Update sums from bottom to the
        # top of Segment Tree
        tm = (tl + tr) // 2
        update(a, pos, tl, tm, v * 2)
        update(a, pos, tm + 1, tr, v * 2 + 1)
 
        # Update MAX tree
        MAX[v] = max(MAX[v * 2], max(MAX[v * 2 + 1], suf[v * 2] + pref[v * 2 + 1]))
         
        # Update pref tree
        pref[v] = max(pref[v * 2], pref[2 * v] + (pref[2 * v] == tm - tl + 1) * pref[v * 2 + 1])
         
        # Update suf tree
        suf[v] = max(suf[v * 2 + 1], suf[2 * v + 1] + (suf[2 * v + 1] == tr - tm) * suf[v * 2])
 
# Function to perform given queries
def solveQueries(arr, n, Q, k):
    global MAX
     
    # Stores count of queries
    cntQuery = len(Q)
    build(arr, 0, n - 1, 1)
 
    # Traverse each query
    for i in range(cntQuery):
        if (Q[i][0] == 1):
           
            # Print longest length of subarray in [1, N]
            print(MAX[1],end = " ")
 
        else:
            # Flip the character
            arr[Q[i][1] - 1] ^= 1
            update(arr, Q[i][1] - 1, 0, n - 1, 1)
 
# Driver Code
if __name__ == '__main__':
   
    # Size of array
    N = 10
     
    # Given array
    arr =  [1, 1, 0, 1, 1, 1, 0, 0, 1, 1]
     
    # Given queries
    Q =  [[1], [2, 3], [1]]
     
    # Number of queries
    K = 3
    solveQueries(arr, N, Q, K)
     
    # This code is contributed by SURENDRA_GANGWAR.

C#

// C# Program for the above approach
using System;
class GFG
{
   
static readonly int INF = 1000000;
 
// Arrays to store prefix sums, suffix
// and MAX's node respectively
static int []pref = new int[500005];
static int []suf = new int[500005];
static int []MAX = new int[500005];
 
// Function to conSegment Tree
static void build(int []a, int tl, int tr, int v)
{
    if (tl == tr)
    {
 
        // MAX array for node MAX
        MAX[v] = a[tl];
 
        // Array for prefix sum node
        pref[v] = a[tl];
       
        // Array for suffix sum node
        suf[v] = a[tl];
    }
    else
    {
        int tm = (tl + tr) / 2;
        build(a, tl, tm, v * 2);
        build(a, tm + 1, tr, v * 2 + 1);
 
        // Calculate MAX node
        MAX[v] = Math.Max(MAX[v * 2],
                     Math.Max(MAX[v * 2 + 1],
                         suf[v * 2] + pref[v * 2 + 1]));
        pref[v] = Math.Max(pref[v * 2],
                      pref[2 * v]
                          + (pref[2 * v] == (tm - tl + 1)?1:0)
                                * pref[v * 2 + 1]);
        suf[v] = Math.Max(
            suf[v * 2 + 1],
            suf[2 * v + 1]
                + suf[v * 2] * (suf[2 * v + 1] == (tr - tm)?1:0));
    }
}
 
// Function to update Segment Tree
static void update(int []a, int pos, int tl,
            int tr, int v)
{
    if (tl > pos || tr < pos)
    {
        return;
    }
 
    // Update at position
    if (tl == tr && tl == pos)
    {
        MAX[v] = a[pos];
        pref[v] = a[pos];
        suf[v] = a[pos];
    }
    else
    {
 
        // Update sums from bottom to the
        // top of Segment Tree
        int tm = (tl + tr) / 2;
        update(a, pos, tl, tm, v * 2);
        update(a, pos, tm + 1, tr, v * 2 + 1);
 
        // Update MAX tree
        MAX[v] = Math.Max(MAX[v * 2],
                     Math.Max(MAX[v * 2 + 1],
                         suf[v * 2] + pref[v * 2 + 1]));
         
      // Update pref tree
        pref[v] = Math.Max(pref[v * 2],
                      pref[2 * v]
                          + (pref[2 * v] == (tm - tl + 1)?1:0)
                                * pref[v * 2 + 1]);
         
      // Update suf tree
        suf[v] = Math.Max(suf[v * 2 + 1],
                     suf[2 * v + 1]
                         + (suf[2 * v + 1] == (tr - tm)?1:0)
                               * suf[v * 2]);
    }
}
 
// Function to perform given queries
static void solveQueries(int []arr, int n,
                  int[,] Q, int k)
{
   
    // Stores count of queries
    int cntQuery = Q.GetLength(0);
    build(arr, 0, n - 1, 1);
 
    // Traverse each query
    for (int i = 0; i < cntQuery; i++)
    {
        if (Q[i, 0] == 1)
        {
 
            // Print longest length of subarray in [1, N]
            Console.Write(MAX[1] + " ");
        }
 
        else
        {
 
            // Flip the character
            arr[Q[i, 1] - 1] ^= 1;
            update(arr, Q[i, 1] - 1, 0, n - 1, 1);
        }
    }
}
 
// Driver Code
public static void Main(String[] args)
{
   
    // Size of array
    int N = 10;
 
    // Given array
    int []arr = { 1, 1, 0, 1, 1,
                  1, 0, 0, 1, 1 };
 
    // Given queries
    int [,]Q = { { 1,0 }, { 2, 3 }, { 1,0 } };
 
    // Number of queries
    int K = 3;
    solveQueries(arr, N, Q, K);
}
}
 
// This code is contributed by 29AjayKumar
输出:
3 6

时间复杂度: O(max(K * log(N),N * log(N)))
辅助空间: O(4 * N)