# Count of Ks in the Array for a given range of indices after array updates for Q queries

• Difficulty Level : Hard
• Last Updated : 21 Oct, 2021

Given an array arr[] of N integers, an integer K, and Q queries of the type as explained below:

• (1, L, R): If the query is of type 1, then find the number of Ks over the range [L, R].
• (2, P, X): If the query is of type 2, then update the array element at index P to X.

The task is to perform the queries on the given Array and print the result accordingly.

Examples:

Input: K = 0, arr[] = {9, 5, 7, 6, 9, 0, 0, 0, 0, 5, 6, 7, 3, 9, 0, 7, 0, 9, 0}, query[][2] = {{1, 5, 14 }, {2, 6, 1 }, {1, 0, 8 }, {2, 13, 0 }, {1, 6, 18 } }
Output: 5
3
6
Explanation:
Following are the values of queries performed:

1. first query is of type 1, then the count of 0s(= K) in the range [5, 14] is 5.
2. second query is of type 2 so update the value of array element at index P = 6 to X = 1 i.e., arr[6] = 1.
The modified array is {9 5 7 6 9 0 1 0 0 5 6 7 3 9 0 7 0 9 0}.
3. third query is of type 1, then the count of 0s(= K) in the range [0, 8] is 3.
4. fourth query is of type 2 so update the value of array element at index P = 13 to X = 0 i.e., arr[13] = 0.
The modified array is {9 5 7 6 9 0 1 0 0 5 6 7 3 0 0 7 0 9 0}.
5. fifth query is of type 1, then the count of 0s in the range [6, 18] is 6.

Therefore, print 5, 3, and 6 as the answer to the queries.

Input: K = 6, arr[] = {9, 5, 7, 6}, query[][2] = {{1, 1, 2}, {2, 0, 0} }
Output: 0

Naive Approach: The simplest approach to solve the given problem is to change the array element for the query of the second type and for the first type of query, traverse the array over the range [L, R] and print the count of K in it.

Below is the implementation of the above approach:

## 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<``int``>& 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<``int``> 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

 ``

Output:

```5
3
6```

Time complexity: O(Q*N)
Auxiliary Space: O(1)

Efficient Approach: The above approach can also be optimized by using a Segment Tree to calculate the count of Ks from a starting index to the ending index, the time complexity for this query in the Segment Tree is O(log(N)). To change the value and updating the segment tree, update the segment tree in O(log(N)) time. Follow the steps below to solve the given problem:

• Define a function Build_tree that recursively calls itself once with either the left or the right child, or twice, once for the left and once for the right child (like divide and conquer).
• Define a function frequency similar to the Build_tree function and find the sum of the count of Ks.
• Define a function update that passes the current tree vertex, and it recursively calls itself with one of the two-child vertices, and after that recomputes its zero count value, similar to how it is done in the Build_tree method.
• Initialize a vector seg_tree and call the function Build_tree to build the initial segment tree.
• Iterate over the range [1, Q] using the variable i and perform the following steps:
• If the type of the current query is 1, then call the function frequency(1, 0, n-1, l, r, seg_tree) to count the frequency of Ks.
• Else, update the value in the array arr[] and call the function update(1, 0, n-1, pos, new_val, seg_tree) to update the value in the segment tree.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;` `// Function to build the segment tree``void` `build_tree(vector<``int``>& a,``                ``vector<``int``>& 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<``int``>& 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<``int``>& 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<``int``>& arr,``           ``vector >& query)``{``    ``vector<``int``> 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<``int``> 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

 ``

Output:

```5
3
6```

Time Complexity: O(Q*log(N) + N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up