Q 查询的数组更新后给定索引范围的数组中的 K 计数
给定一个包含N个整数的数组arr[] 、一个整数K和Q类型的查询,如下所述:
- (1, L, R) :如果查询的类型为1 ,则在[L, R]范围内查找K的数量。
- (2, P, X) :如果查询的类型为2 ,则将索引P处的数组元素更新为X 。
任务是对给定的数组执行查询并相应地打印结果。
例子:
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:
- first query is of type 1, then the count of 0s(= K) in the range [5, 14] is 5.
- 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}. - third query is of type 1, then the count of 0s(= K) in the range [0, 8] is 3.
- 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}. - 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
朴素方法:解决给定问题的最简单方法是更改第二类查询的数组元素,对于第一类查询,遍历范围[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)