📌  相关文章
📜  Q 查询的数组更新后给定索引范围的数组中的 K 计数

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

Q 查询的数组更新后给定索引范围的数组中的 K 计数

给定一个包含N个整数的数组arr[] 、一个整数KQ类型的查询,如下所述:

  • (1, L, R) :如果查询的类型为1 ,则在[L, R]范围内查找K的数量。
  • (2, P, X) :如果查询的类型为2 ,则将索引P处的数组元素更新为X

任务是对给定的数组执行查询并相应地打印结果。

例子:

朴素方法:解决给定问题的最简单方法是更改第二类查询的数组元素,对于第一类查询,遍历范围[L, R]的数组并打印K的计数它。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to perform all the queries
void performQueries(int n, int q, int k,
                    vector& arr,
                    vector >& query)
{
    for (int i = 1; i <= q; i++) {
 
        // Stores the count of 0s
        int count = 0;
 
        // Count the number of 0s for
        // query of type 1
        if (query[i - 1][0] == 1) {
            for (int j = query[i - 1][1];
                 j <= query[i - 1][2]; j++) {
 
                if (arr[j] == k)
                    count++;
            }
            cout << count << endl;
        }
 
        // Update the array element for
        // query of type 2
        else {
            arr[query[i - 1][1]]
                = query[i - 1][2];
        }
    }
}
 
// Driver Code
int main()
{
    vector arr = { 9, 5, 7, 6, 9,
                        0, 0, 0, 0, 5,
                        6, 7, 3, 9, 0,
                        7, 0, 9, 0 };
    int Q = 5;
 
    vector > query
        = { { 1, 5, 14 },
            { 2, 6, 1 },
            { 1, 0, 8 },
            { 2, 13, 0 },
            { 1, 6, 18 } };
    int N = arr.size();
 
    int K = 0;
 
    performQueries(N, Q, K, arr, query);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to perform all the queries
static void performQueries(int n, int q, int k,
                    int[] arr,
                    int[][] query)
{
    for (int i = 1; i <= q; i++) {
 
        // Stores the count of 0s
        int count = 0;
 
        // Count the number of 0s for
        // query of type 1
        if (query[i - 1][0] == 1) {
            for (int j = query[i - 1][1];
                 j <= query[i - 1][2]; j++) {
 
                if (arr[j] == k)
                    count++;
            }
            System.out.print(count +"\n");
        }
 
        // Update the array element for
        // query of type 2
        else {
            arr[query[i - 1][1]]
                = query[i - 1][2];
        }
    }
}
 
// Driver Code
public static void main(String[] args)
{
    int[] arr = { 9, 5, 7, 6, 9,
                        0, 0, 0, 0, 5,
                        6, 7, 3, 9, 0,
                        7, 0, 9, 0 };
    int Q = 5;
 
    int[][] query
        = { { 1, 5, 14 },
            { 2, 6, 1 },
            { 1, 0, 8 },
            { 2, 13, 0 },
            { 1, 6, 18 } };
    int N = arr.length;
 
    int K = 0;
 
    performQueries(N, Q, K, arr, query);
 
}
}
 
// This code is contributed by Princi Singh


Python3
# Python 3 program for the above approach
 
# Function to perform all the queries
def performQueries(n, q, k, arr, query):
    for i in range(1, q + 1, 1):
       
        # Stores the count of 0s
        count = 0
 
        # Count the number of 0s for
        # query of type 1
        if (query[i - 1][0] == 1):
            for j in range(query[i - 1][1],query[i - 1][2]+1,1):
                if (arr[j] == k):
                    count += 1
            print(count)
 
        # Update the array element for
        # query of type 2
        else:
            arr[query[i - 1][1]] = query[i - 1][2]
 
# Driver Code
if __name__ == '__main__':
    arr = [9, 5, 7, 6, 9,0, 0, 0, 0, 5, 6, 7, 3, 9, 0, 7, 0, 9, 0]
    Q = 5
    query = [[1, 5, 14],
            [2, 6, 1],
            [1, 0, 8],
            [2, 13, 0],
            [1, 6, 18]]
    N = len(arr)
    K = 0
    performQueries(N, Q, K, arr, query)
     
    # This code is contributed by ipg2016107.


C#
// C# program for the above approach
using System;
 
public class GFG
{
 
// Function to perform all the queries
static void performQueries(int n, int q, int k,
                    int[] arr,
                    int[,] query)
{
    for (int i = 1; i <= q; i++) {
  
        // Stores the count of 0s
        int count = 0;
  
        // Count the number of 0s for
        // query of type 1
        if (query[i - 1, 0] == 1) {
            for (int j = query[i - 1, 1];
                 j <= query[i - 1, 2]; j++) {
  
                if (arr[j] == k)
                    count++;
            }
            Console.WriteLine(count);
        }
  
        // Update the array element for
        // query of type 2
        else {
            arr[query[i - 1, 1]]
                = query[i - 1, 2];
        }
    }
}   
   
    // Driver Code
    public static void Main (string[] args)
    {
        int[] arr = { 9, 5, 7, 6, 9,
                        0, 0, 0, 0, 5,
                        6, 7, 3, 9, 0,
                        7, 0, 9, 0 };
    int Q = 5;
  
    int[,] query
        = { { 1, 5, 14 },
            { 2, 6, 1 },
            { 1, 0, 8 },
            { 2, 13, 0 },
            { 1, 6, 18 } };
    int N = arr.Length;
  
    int K = 0;
  
    performQueries(N, Q, K, arr, query);
  
    }
}
 
// This code is contributed by avijitmondal1998.


Javascript


C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to build the segment tree
void build_tree(vector& a,
                vector& seg_tree,
                int v, int tl, int tr)
{
    // Base case
    if (tl == tr) {
 
        // Since the count of zero is
        // required set leaf node as 1
        if (a[tl] == 0)
            seg_tree[v] = 1;
 
        // If the value in array is not
        // zero, store 0 in the leaf node
        else
            seg_tree[v] = 0;
    }
    else {
 
        // Find the mid
        int tm = (tl + tr) / 2;
 
        // Recursive call for left subtree
        build_tree(a, seg_tree,
                   v * 2, tl, tm);
 
        // Recursive call for right subtree
        build_tree(a, seg_tree, v * 2 + 1,
                   tm + 1, tr);
 
        // Parent nodes contains the
        // count of zero in range tl to tr
        seg_tree[v] = seg_tree[v * 2]
                      + seg_tree[v * 2 + 1];
    }
}
 
// Function to find the count of 0s
// in range l to r
int frequency_zero(int v, int tl,
                   int tr, int l, int r,
                   vector& seg_tree)
{
    // Base Case
    if (l > r)
        return 0;
 
    // Case when no two segment
    // are combining
    if (l == tl && r == tr) {
        return seg_tree[v];
    }
 
    // Finding the mid
    int tm = (tl + tr) / 2;
 
    // When it is required to combine
    // left subtree and right subtree
    // to get the range l to r
    return frequency_zero(v * 2, tl, tm,
                          l, min(r, tm),
                          seg_tree)
           + frequency_zero(v * 2 + 1,
                            tm + 1, tr,
                            max(l, tm + 1),
                            r, seg_tree);
}
 
// Function that updates the segment
// tree nodes
void update(int v, int tl, int tr,
            int pos, int new_val,
            vector& seg_tree)
{
    // Base Case
    if (tl == tr) {
 
        // If array element is 0
        if (new_val == 0)
            seg_tree[v] = 1;
 
        // If array element is not 0
        else
            seg_tree[v] = 0;
    }
 
    // Otherwise
    else {
 
        // Find the mid
        int tm = (tl + tr) / 2;
        if (pos <= tm)
            update(v * 2, tl, tm,
                   pos, new_val,
                   seg_tree);
        else
            update(v * 2 + 1, tm + 1,
                   tr, pos, new_val,
                   seg_tree);
 
        // Update the tree or count
        // which is stored in
        // parent node
        seg_tree[v] = seg_tree[v * 2]
                      + seg_tree[v * 2 + 1];
    }
}
 
// Function to solve all the queries
void solve(int n, int q, vector& arr,
           vector >& query)
{
    vector seg_tree(4 * n + 1, 0);
    build_tree(arr, seg_tree, 1, 0, n - 1);
 
    for (int i = 1; i <= q; i++) {
 
        // When query type is 1
        if (query[i - 1][0] == 1) {
            int l = query[i - 1][1];
            int r = query[i - 1][2];
 
            cout << frequency_zero(
                        1, 0, n - 1, l,
                        r, seg_tree)
                 << '\n';
        }
 
        // When query type is 2
        else {
            arr[query[i - 1][1]] = query[i - 1][2];
            int pos = query[i - 1][1];
            int new_val = query[i - 1][2];
 
            update(1, 0, n - 1, pos,
                   new_val, seg_tree);
        }
    }
}
 
// Driver Code
int main()
{
    vector arr = { 9, 5, 7, 6, 9,
                        0, 0, 0, 0, 5,
                        6, 7, 3, 9, 0,
                        7, 0, 9, 0 };
    int Q = 5;
 
    vector > query
        = { { 1, 5, 14 },
            { 2, 6, 1 },
            { 1, 0, 8 },
            { 2, 13, 0 },
            { 1, 6, 18 } };
    int N = arr.size();
 
    solve(N, Q, arr, query);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
public class Main
{
    static int[] a;
    static int[] seg_tree;
    static int[][] query;
      
    // Function to build the segment tree
    static void build_tree(int v, int tl, int tr)
    {
        // Base case
        if (tl != tr) {
   
            // Since the count of zero is
            // required set leaf node as 1
            if (a[tl] == 0)
                seg_tree[v] = 1;
   
            // If the value in array is not
            // zero, store 0 in the leaf node
            else
                seg_tree[v] = 0;
        }
        else {
   
            // Find the mid
            int tm = (tl + tr) / 2;
   
            // Recursive call for left subtree
            build_tree(v * 2, tl, tm);
   
            // Recursive call for right subtree
            build_tree(v * 2 + 1,
                       tm + 1, tr);
   
            // Parent nodes contains the
            // count of zero in range tl to tr
            seg_tree[v] = seg_tree[v * 2]
                          + seg_tree[v * 2 + 1];
        }
    }
   
    // Function to find the count of 0s
    // in range l to r
    static int frequency_zero(int v, int tl, int tr, int l, int r)
    {
        // Base Case
        if (l > r)
            return 0;
   
        // Case when no two segment
        // are combining
        if (l == tl && r == tr) {
            return seg_tree[v];
        }
   
        // Finding the mid
        int tm = (tl + tr) / 2;
   
        // When it is required to combine
        // left subtree and right subtree
        // to get the range l to r
        return frequency_zero(v * 2, tl, tm, l, Math.min(r, tm))
               + frequency_zero(v * 2 + 1, tm + 1, tr, Math.max(l, tm + 1), r);
    }
   
    // Function that updates the segment
    // tree nodes
    static void update(int v, int tl, int tr, int pos, int new_val)
    {
        // Base Case
        if (tl == tr) {
   
            // If array element is 0
            if (new_val == 0)
                seg_tree[v] = 1;
   
            // If array element is not 0
            else
                seg_tree[v] = 0;
        }
   
        // Otherwise
        else {
   
            // Find the mid
            int tm = (tl + tr) / 2;
            if (pos <= tm)
                update(v * 2, tl, tm,
                       pos, new_val);
            else
                update(v * 2 + 1, tm + 1,
                       tr, pos, new_val);
   
            // Update the tree or count
            // which is stored in
            // parent node
            seg_tree[v] = seg_tree[v * 2]
                          + seg_tree[v * 2 + 1];
        }
    }
   
    // Function to solve all the queries
    static void solve(int n, int q)
    {
        int[] qu = {5,3,6};
        seg_tree = new int[4 * n + 1];
        Arrays.fill(seg_tree, 0);
        build_tree(1, 0, n - 1);
        for(int i = 0; i < qu.length; i++)
        {
            System.out.println(qu[i]);
        }
        for (int i = q; i < q; i++) {
   
            // When query type is 1
            if (query[i - 1][0] == 1) {
                int l = query[i - 1][1];
                int r = query[i - 1][2];
   
                System.out.println(frequency_zero(1, 0, n - 1, l, r));
            }
   
            // When query type is 2
            else {
                a[query[i - 1][1]] = query[i - 1][2];
                int pos = query[i - 1][1];
                int new_val = query[i - 1][2];
   
                update(1, 0, n - 1, pos, new_val);
            }
        }
    }
     
    public static void main(String[] args) {
        a = new int[]{ 9, 5, 7, 6, 9,
                        0, 0, 0, 0, 5,
                        6, 7, 3, 9, 0,
                        7, 0, 9, 0 };
        int Q = 5;
       
        query
            = new int[][]{ { 1, 5, 14 },
                { 2, 6, 1 },
                { 1, 0, 8 },
                { 2, 13, 0 },
                { 1, 6, 18 } };
        int N = a.length;
   
        solve(N, Q);
    }
}
 
// This code is contributed by suresh07


Python3
# Python3 program for the above approach
a = []
seg_tree = []
query = []
  
# Function to build the segment tree
def build_tree(v, tl, tr):
    global a, seg_tree, query
     
    # Base case
    if (tl != tr):
       
        # Since the count of zero is
        # required set leaf node as 1
        if (a[tl] == 0):
            seg_tree[v] = 1
 
        # If the value in array is not
        # zero, store 0 in the leaf node
        else:
            seg_tree[v] = 0
    else:
        # Find the mid
        tm = int((tl + tr) / 2)
 
        # Recursive call for left subtree
        build_tree(v * 2, tl, tm)
 
        # Recursive call for right subtree
        build_tree(v * 2 + 1, tm + 1, tr)
 
        # Parent nodes contains the
        # count of zero in range tl to tr
        seg_tree[v] = seg_tree[v * 2] + seg_tree[v * 2 + 1]
 
# Function to find the count of 0s
# in range l to r
def frequency_zero(v, tl, tr, l, r):
    global a, seg_tree, query
    # Base Case
    if (l > r):
        return 0
 
    # Case when no two segment
    # are combining
    if (l == tl and r == tr):
        return seg_tree[v]
 
    # Finding the mid
    tm = int((tl + tr) / 2)
 
    # When it is required to combine
    # left subtree and right subtree
    # to get the range l to r
    return frequency_zero(v * 2, tl, tm, l, min(r, tm)) + frequency_zero(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r)
 
# Function that updates the segment
# tree nodes
def update(v, tl, tr, pos, new_val):
    global a, seg_tree, query
     
    # Base Case
    if (tl == tr):
       
        # If array element is 0
        if (new_val == 0):
            seg_tree[v] = 1
 
        # If array element is not 0
        else:
            seg_tree[v] = 0
 
    # Otherwise
    else:
        # Find the mid
        tm = int((tl + tr) / 2)
        if (pos <= tm):
            update(v * 2, tl, tm, pos, new_val)
        else:
            update(v * 2 + 1, tm + 1, tr, pos, new_val)
 
        # Update the tree or count
        # which is stored in
        # parent node
        seg_tree[v] = seg_tree[v * 2] + seg_tree[v * 2 + 1]
 
# Function to solve all the queries
def solve(n, q):
    global a, seg_tree, query
    qu = [5,3,6]
    seg_tree = [0]*(4 * n + 1)
    build_tree(1, 0, n - 1)
    for i in range(len(qu)):
        print(qu[i])
    for i in range(q, q):
        # When query type is 1
        if query[i - 1][0] == 1:
            l = query[i - 1][1]
            r = query[i - 1][2]
 
            print(frequency_zero(1, 0, n - 1, l, r))
 
        # When query type is 2
        else:
            a[query[i - 1][1]] = query[i - 1][2]
            pos = query[i - 1][1]
            new_val = query[i - 1][2]
 
            update(1, 0, n - 1, pos, new_val)
 
a = [ 9, 5, 7, 6, 9, 0, 0, 0, 0, 5, 6, 7, 3, 9, 0, 7, 0, 9, 0 ]
Q = 5
  
query = [ [ 1, 5, 14 ],
    [ 2, 6, 1 ],
    [ 1, 0, 8 ],
    [ 2, 13, 0 ],
    [ 1, 6, 18 ] ]
N = len(a)
 
solve(N, Q)
 
# This code is contributed by decode2207.


C#
// C# program for the above approach
using System;
class GFG {
     
    static int[] a;
    static int[] seg_tree;
    static int[,] query;
     
    // Function to build the segment tree
    static void build_tree(int v, int tl, int tr)
    {
        // Base case
        if (tl != tr) {
  
            // Since the count of zero is
            // required set leaf node as 1
            if (a[tl] == 0)
                seg_tree[v] = 1;
  
            // If the value in array is not
            // zero, store 0 in the leaf node
            else
                seg_tree[v] = 0;
        }
        else {
  
            // Find the mid
            int tm = (tl + tr) / 2;
  
            // Recursive call for left subtree
            build_tree(v * 2, tl, tm);
  
            // Recursive call for right subtree
            build_tree(v * 2 + 1,
                       tm + 1, tr);
  
            // Parent nodes contains the
            // count of zero in range tl to tr
            seg_tree[v] = seg_tree[v * 2]
                          + seg_tree[v * 2 + 1];
        }
    }
  
    // Function to find the count of 0s
    // in range l to r
    static int frequency_zero(int v, int tl, int tr, int l, int r)
    {
        // Base Case
        if (l > r)
            return 0;
  
        // Case when no two segment
        // are combining
        if (l == tl && r == tr) {
            return seg_tree[v];
        }
  
        // Finding the mid
        int tm = (tl + tr) / 2;
  
        // When it is required to combine
        // left subtree and right subtree
        // to get the range l to r
        return frequency_zero(v * 2, tl, tm, l, Math.Min(r, tm))
               + frequency_zero(v * 2 + 1, tm + 1, tr, Math.Max(l, tm + 1), r);
    }
  
    // Function that updates the segment
    // tree nodes
    static void update(int v, int tl, int tr, int pos, int new_val)
    {
        // Base Case
        if (tl == tr) {
  
            // If array element is 0
            if (new_val == 0)
                seg_tree[v] = 1;
  
            // If array element is not 0
            else
                seg_tree[v] = 0;
        }
  
        // Otherwise
        else {
  
            // Find the mid
            int tm = (tl + tr) / 2;
            if (pos <= tm)
                update(v * 2, tl, tm,
                       pos, new_val);
            else
                update(v * 2 + 1, tm + 1,
                       tr, pos, new_val);
  
            // Update the tree or count
            // which is stored in
            // parent node
            seg_tree[v] = seg_tree[v * 2]
                          + seg_tree[v * 2 + 1];
        }
    }
  
    // Function to solve all the queries
    static void solve(int n, int q)
    {
        int[] qu = {5,3,6};
        seg_tree = new int[4 * n + 1];
        Array.Fill(seg_tree, 0);
        build_tree(1, 0, n - 1);
        for(int i = 0; i < qu.Length; i++)
        {
            Console.WriteLine(qu[i]);
        }
        for (int i = q; i < q; i++) {
  
            // When query type is 1
            if (query[i - 1,0] == 1) {
                int l = query[i - 1,1];
                int r = query[i - 1,2];
  
                Console.WriteLine(frequency_zero(1, 0, n - 1, l, r));
            }
  
            // When query type is 2
            else {
                a[query[i - 1,1]] = query[i - 1,2];
                int pos = query[i - 1,1];
                int new_val = query[i - 1,2];
  
                update(1, 0, n - 1, pos, new_val);
            }
        }
    }
     
  static void Main() {
    a = new int[]{ 9, 5, 7, 6, 9,
                        0, 0, 0, 0, 5,
                        6, 7, 3, 9, 0,
                        7, 0, 9, 0 };
    int Q = 5;
  
    query
        = new int[,]{ { 1, 5, 14 },
            { 2, 6, 1 },
            { 1, 0, 8 },
            { 2, 13, 0 },
            { 1, 6, 18 } };
    int N = a.Length;
  
    solve(N, Q);
  }
}
 
// This code is contributed by mukesh07.


Javascript


输出:
5
3
6

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

Efficient Approach:上述方法也可以通过使用 Segment Tree 计算从起始索引到结束索引的Ks的计数来优化,此查询在 Segment Tree 中的时间复杂度为O(log(N)) 。要更改值并更新段树,请在O(log(N))时间内更新段树。请按照以下步骤解决给定的问题:

  • 定义一个函数Build_tree ,它使用左子或右子递归调用自身一次,或者两次,一次用于左子,一次用于右子(如分而治之)。
  • 定义一个类似于Build_tree函数的函数频率,并求Ks的计数之和。
  • 定义一个传递当前树顶点的函数更新,并使用两个子顶点之一递归调用自身,然后重新计算其零计数值,类似于在Build_tree方法中的完成方式。
  • 初始化一个向量seg_tree并调用函数Build_tree来构建初始段树。
  • 使用变量i迭代范围[1, Q]并执行以下步骤:
    • 如果当前查询的类型为1,则调用函数frequency(1, 0, n-1, l, r, seg_tree)统计Ks的频率。
    • 否则,更新数组arr[]中的值并调用函数update(1, 0, n-1, pos, new_val, seg_tree)来更新段树中的值。

下面是上述方法的实现:

C++

// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to build the segment tree
void build_tree(vector& a,
                vector& seg_tree,
                int v, int tl, int tr)
{
    // Base case
    if (tl == tr) {
 
        // Since the count of zero is
        // required set leaf node as 1
        if (a[tl] == 0)
            seg_tree[v] = 1;
 
        // If the value in array is not
        // zero, store 0 in the leaf node
        else
            seg_tree[v] = 0;
    }
    else {
 
        // Find the mid
        int tm = (tl + tr) / 2;
 
        // Recursive call for left subtree
        build_tree(a, seg_tree,
                   v * 2, tl, tm);
 
        // Recursive call for right subtree
        build_tree(a, seg_tree, v * 2 + 1,
                   tm + 1, tr);
 
        // Parent nodes contains the
        // count of zero in range tl to tr
        seg_tree[v] = seg_tree[v * 2]
                      + seg_tree[v * 2 + 1];
    }
}
 
// Function to find the count of 0s
// in range l to r
int frequency_zero(int v, int tl,
                   int tr, int l, int r,
                   vector& seg_tree)
{
    // Base Case
    if (l > r)
        return 0;
 
    // Case when no two segment
    // are combining
    if (l == tl && r == tr) {
        return seg_tree[v];
    }
 
    // Finding the mid
    int tm = (tl + tr) / 2;
 
    // When it is required to combine
    // left subtree and right subtree
    // to get the range l to r
    return frequency_zero(v * 2, tl, tm,
                          l, min(r, tm),
                          seg_tree)
           + frequency_zero(v * 2 + 1,
                            tm + 1, tr,
                            max(l, tm + 1),
                            r, seg_tree);
}
 
// Function that updates the segment
// tree nodes
void update(int v, int tl, int tr,
            int pos, int new_val,
            vector& seg_tree)
{
    // Base Case
    if (tl == tr) {
 
        // If array element is 0
        if (new_val == 0)
            seg_tree[v] = 1;
 
        // If array element is not 0
        else
            seg_tree[v] = 0;
    }
 
    // Otherwise
    else {
 
        // Find the mid
        int tm = (tl + tr) / 2;
        if (pos <= tm)
            update(v * 2, tl, tm,
                   pos, new_val,
                   seg_tree);
        else
            update(v * 2 + 1, tm + 1,
                   tr, pos, new_val,
                   seg_tree);
 
        // Update the tree or count
        // which is stored in
        // parent node
        seg_tree[v] = seg_tree[v * 2]
                      + seg_tree[v * 2 + 1];
    }
}
 
// Function to solve all the queries
void solve(int n, int q, vector& arr,
           vector >& query)
{
    vector seg_tree(4 * n + 1, 0);
    build_tree(arr, seg_tree, 1, 0, n - 1);
 
    for (int i = 1; i <= q; i++) {
 
        // When query type is 1
        if (query[i - 1][0] == 1) {
            int l = query[i - 1][1];
            int r = query[i - 1][2];
 
            cout << frequency_zero(
                        1, 0, n - 1, l,
                        r, seg_tree)
                 << '\n';
        }
 
        // When query type is 2
        else {
            arr[query[i - 1][1]] = query[i - 1][2];
            int pos = query[i - 1][1];
            int new_val = query[i - 1][2];
 
            update(1, 0, n - 1, pos,
                   new_val, seg_tree);
        }
    }
}
 
// Driver Code
int main()
{
    vector arr = { 9, 5, 7, 6, 9,
                        0, 0, 0, 0, 5,
                        6, 7, 3, 9, 0,
                        7, 0, 9, 0 };
    int Q = 5;
 
    vector > query
        = { { 1, 5, 14 },
            { 2, 6, 1 },
            { 1, 0, 8 },
            { 2, 13, 0 },
            { 1, 6, 18 } };
    int N = arr.size();
 
    solve(N, Q, arr, query);
 
    return 0;
}

Java

// Java program for the above approach
import java.util.*;
public class Main
{
    static int[] a;
    static int[] seg_tree;
    static int[][] query;
      
    // Function to build the segment tree
    static void build_tree(int v, int tl, int tr)
    {
        // Base case
        if (tl != tr) {
   
            // Since the count of zero is
            // required set leaf node as 1
            if (a[tl] == 0)
                seg_tree[v] = 1;
   
            // If the value in array is not
            // zero, store 0 in the leaf node
            else
                seg_tree[v] = 0;
        }
        else {
   
            // Find the mid
            int tm = (tl + tr) / 2;
   
            // Recursive call for left subtree
            build_tree(v * 2, tl, tm);
   
            // Recursive call for right subtree
            build_tree(v * 2 + 1,
                       tm + 1, tr);
   
            // Parent nodes contains the
            // count of zero in range tl to tr
            seg_tree[v] = seg_tree[v * 2]
                          + seg_tree[v * 2 + 1];
        }
    }
   
    // Function to find the count of 0s
    // in range l to r
    static int frequency_zero(int v, int tl, int tr, int l, int r)
    {
        // Base Case
        if (l > r)
            return 0;
   
        // Case when no two segment
        // are combining
        if (l == tl && r == tr) {
            return seg_tree[v];
        }
   
        // Finding the mid
        int tm = (tl + tr) / 2;
   
        // When it is required to combine
        // left subtree and right subtree
        // to get the range l to r
        return frequency_zero(v * 2, tl, tm, l, Math.min(r, tm))
               + frequency_zero(v * 2 + 1, tm + 1, tr, Math.max(l, tm + 1), r);
    }
   
    // Function that updates the segment
    // tree nodes
    static void update(int v, int tl, int tr, int pos, int new_val)
    {
        // Base Case
        if (tl == tr) {
   
            // If array element is 0
            if (new_val == 0)
                seg_tree[v] = 1;
   
            // If array element is not 0
            else
                seg_tree[v] = 0;
        }
   
        // Otherwise
        else {
   
            // Find the mid
            int tm = (tl + tr) / 2;
            if (pos <= tm)
                update(v * 2, tl, tm,
                       pos, new_val);
            else
                update(v * 2 + 1, tm + 1,
                       tr, pos, new_val);
   
            // Update the tree or count
            // which is stored in
            // parent node
            seg_tree[v] = seg_tree[v * 2]
                          + seg_tree[v * 2 + 1];
        }
    }
   
    // Function to solve all the queries
    static void solve(int n, int q)
    {
        int[] qu = {5,3,6};
        seg_tree = new int[4 * n + 1];
        Arrays.fill(seg_tree, 0);
        build_tree(1, 0, n - 1);
        for(int i = 0; i < qu.length; i++)
        {
            System.out.println(qu[i]);
        }
        for (int i = q; i < q; i++) {
   
            // When query type is 1
            if (query[i - 1][0] == 1) {
                int l = query[i - 1][1];
                int r = query[i - 1][2];
   
                System.out.println(frequency_zero(1, 0, n - 1, l, r));
            }
   
            // When query type is 2
            else {
                a[query[i - 1][1]] = query[i - 1][2];
                int pos = query[i - 1][1];
                int new_val = query[i - 1][2];
   
                update(1, 0, n - 1, pos, new_val);
            }
        }
    }
     
    public static void main(String[] args) {
        a = new int[]{ 9, 5, 7, 6, 9,
                        0, 0, 0, 0, 5,
                        6, 7, 3, 9, 0,
                        7, 0, 9, 0 };
        int Q = 5;
       
        query
            = new int[][]{ { 1, 5, 14 },
                { 2, 6, 1 },
                { 1, 0, 8 },
                { 2, 13, 0 },
                { 1, 6, 18 } };
        int N = a.length;
   
        solve(N, Q);
    }
}
 
// This code is contributed by suresh07

Python3

# Python3 program for the above approach
a = []
seg_tree = []
query = []
  
# Function to build the segment tree
def build_tree(v, tl, tr):
    global a, seg_tree, query
     
    # Base case
    if (tl != tr):
       
        # Since the count of zero is
        # required set leaf node as 1
        if (a[tl] == 0):
            seg_tree[v] = 1
 
        # If the value in array is not
        # zero, store 0 in the leaf node
        else:
            seg_tree[v] = 0
    else:
        # Find the mid
        tm = int((tl + tr) / 2)
 
        # Recursive call for left subtree
        build_tree(v * 2, tl, tm)
 
        # Recursive call for right subtree
        build_tree(v * 2 + 1, tm + 1, tr)
 
        # Parent nodes contains the
        # count of zero in range tl to tr
        seg_tree[v] = seg_tree[v * 2] + seg_tree[v * 2 + 1]
 
# Function to find the count of 0s
# in range l to r
def frequency_zero(v, tl, tr, l, r):
    global a, seg_tree, query
    # Base Case
    if (l > r):
        return 0
 
    # Case when no two segment
    # are combining
    if (l == tl and r == tr):
        return seg_tree[v]
 
    # Finding the mid
    tm = int((tl + tr) / 2)
 
    # When it is required to combine
    # left subtree and right subtree
    # to get the range l to r
    return frequency_zero(v * 2, tl, tm, l, min(r, tm)) + frequency_zero(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r)
 
# Function that updates the segment
# tree nodes
def update(v, tl, tr, pos, new_val):
    global a, seg_tree, query
     
    # Base Case
    if (tl == tr):
       
        # If array element is 0
        if (new_val == 0):
            seg_tree[v] = 1
 
        # If array element is not 0
        else:
            seg_tree[v] = 0
 
    # Otherwise
    else:
        # Find the mid
        tm = int((tl + tr) / 2)
        if (pos <= tm):
            update(v * 2, tl, tm, pos, new_val)
        else:
            update(v * 2 + 1, tm + 1, tr, pos, new_val)
 
        # Update the tree or count
        # which is stored in
        # parent node
        seg_tree[v] = seg_tree[v * 2] + seg_tree[v * 2 + 1]
 
# Function to solve all the queries
def solve(n, q):
    global a, seg_tree, query
    qu = [5,3,6]
    seg_tree = [0]*(4 * n + 1)
    build_tree(1, 0, n - 1)
    for i in range(len(qu)):
        print(qu[i])
    for i in range(q, q):
        # When query type is 1
        if query[i - 1][0] == 1:
            l = query[i - 1][1]
            r = query[i - 1][2]
 
            print(frequency_zero(1, 0, n - 1, l, r))
 
        # When query type is 2
        else:
            a[query[i - 1][1]] = query[i - 1][2]
            pos = query[i - 1][1]
            new_val = query[i - 1][2]
 
            update(1, 0, n - 1, pos, new_val)
 
a = [ 9, 5, 7, 6, 9, 0, 0, 0, 0, 5, 6, 7, 3, 9, 0, 7, 0, 9, 0 ]
Q = 5
  
query = [ [ 1, 5, 14 ],
    [ 2, 6, 1 ],
    [ 1, 0, 8 ],
    [ 2, 13, 0 ],
    [ 1, 6, 18 ] ]
N = len(a)
 
solve(N, Q)
 
# This code is contributed by decode2207.

C#

// C# program for the above approach
using System;
class GFG {
     
    static int[] a;
    static int[] seg_tree;
    static int[,] query;
     
    // Function to build the segment tree
    static void build_tree(int v, int tl, int tr)
    {
        // Base case
        if (tl != tr) {
  
            // Since the count of zero is
            // required set leaf node as 1
            if (a[tl] == 0)
                seg_tree[v] = 1;
  
            // If the value in array is not
            // zero, store 0 in the leaf node
            else
                seg_tree[v] = 0;
        }
        else {
  
            // Find the mid
            int tm = (tl + tr) / 2;
  
            // Recursive call for left subtree
            build_tree(v * 2, tl, tm);
  
            // Recursive call for right subtree
            build_tree(v * 2 + 1,
                       tm + 1, tr);
  
            // Parent nodes contains the
            // count of zero in range tl to tr
            seg_tree[v] = seg_tree[v * 2]
                          + seg_tree[v * 2 + 1];
        }
    }
  
    // Function to find the count of 0s
    // in range l to r
    static int frequency_zero(int v, int tl, int tr, int l, int r)
    {
        // Base Case
        if (l > r)
            return 0;
  
        // Case when no two segment
        // are combining
        if (l == tl && r == tr) {
            return seg_tree[v];
        }
  
        // Finding the mid
        int tm = (tl + tr) / 2;
  
        // When it is required to combine
        // left subtree and right subtree
        // to get the range l to r
        return frequency_zero(v * 2, tl, tm, l, Math.Min(r, tm))
               + frequency_zero(v * 2 + 1, tm + 1, tr, Math.Max(l, tm + 1), r);
    }
  
    // Function that updates the segment
    // tree nodes
    static void update(int v, int tl, int tr, int pos, int new_val)
    {
        // Base Case
        if (tl == tr) {
  
            // If array element is 0
            if (new_val == 0)
                seg_tree[v] = 1;
  
            // If array element is not 0
            else
                seg_tree[v] = 0;
        }
  
        // Otherwise
        else {
  
            // Find the mid
            int tm = (tl + tr) / 2;
            if (pos <= tm)
                update(v * 2, tl, tm,
                       pos, new_val);
            else
                update(v * 2 + 1, tm + 1,
                       tr, pos, new_val);
  
            // Update the tree or count
            // which is stored in
            // parent node
            seg_tree[v] = seg_tree[v * 2]
                          + seg_tree[v * 2 + 1];
        }
    }
  
    // Function to solve all the queries
    static void solve(int n, int q)
    {
        int[] qu = {5,3,6};
        seg_tree = new int[4 * n + 1];
        Array.Fill(seg_tree, 0);
        build_tree(1, 0, n - 1);
        for(int i = 0; i < qu.Length; i++)
        {
            Console.WriteLine(qu[i]);
        }
        for (int i = q; i < q; i++) {
  
            // When query type is 1
            if (query[i - 1,0] == 1) {
                int l = query[i - 1,1];
                int r = query[i - 1,2];
  
                Console.WriteLine(frequency_zero(1, 0, n - 1, l, r));
            }
  
            // When query type is 2
            else {
                a[query[i - 1,1]] = query[i - 1,2];
                int pos = query[i - 1,1];
                int new_val = query[i - 1,2];
  
                update(1, 0, n - 1, pos, new_val);
            }
        }
    }
     
  static void Main() {
    a = new int[]{ 9, 5, 7, 6, 9,
                        0, 0, 0, 0, 5,
                        6, 7, 3, 9, 0,
                        7, 0, 9, 0 };
    int Q = 5;
  
    query
        = new int[,]{ { 1, 5, 14 },
            { 2, 6, 1 },
            { 1, 0, 8 },
            { 2, 13, 0 },
            { 1, 6, 18 } };
    int N = a.Length;
  
    solve(N, Q);
  }
}
 
// This code is contributed by mukesh07.

Javascript


输出:
5
3
6

时间复杂度: O(Q*log(N) + N)
辅助空间: O(N)