给定大小为N的数组,最初仅由零组成。任务是应用给定的操作q次,并找到数组中除零以外的其他数字的数量。
操作格式:update(l,r,x)::全部更新a [i] = x(l <= i <= r)。
例子:
Input : N = 5, Q = 3,
update(1, 3, 1)
update(0, 1, 2)
update(3, 3, 3)
Output : 3
Explanation : Initially array is {0, 0, 0, 0, 0}. After
applying the operation for the first time array becomes {0, 1, 1, 1, 0}.
After applying the operation for the second time the array becomes
{2, 2, 1, 1, 0}. After applying the operation for the third time the array
becomes {2, 2, 1, 3, 0}. So, a number of different numbers expect zero are 3.
Input : N = 5, Q = 3,
update(1, 1, 4)
update(0, 1, 2)
update(1, 4, 5)
Output : 2
方法 :
每个操作都会建议范围更新,因此请尝试使用延迟传播来更新阵列。使用惰性传播将操作执行Q次后,调用一个函数,该函数可找到数组中不同数字的数量。此函数使用set查找不同数字的计数。
更新和查询操作与段树中的更改和查询操作类似。每当在段树中执行更新查询时,与当前节点关联的所有节点也会被更新,而在延迟传播中,这些节点仅在需要时才被更新,即我们创建一个大小等于给定数组的lazy []数组。其元素将被初始化为0 ,这意味着任何节点最初都没有更新,并且lazy [i]上的任何非零值都表明节点i有一个待处理的更新,仅在查询时(需要时)才会更新。
下面是上述方法的实现:
C++
// CPP implementation for above approach
#include
using namespace std;
#define N 100005
// To store the tree in lazy propagation
int lazy[4 * N];
// To store the different numbers
set se;
// Function to update in the range [x, y) with given value
void update(int x, int y, int value, int id, int l, int r)
{
// check out of bound
if (x >= r or l >= y)
return;
// check for complete overlap
if (x <= l && r <= y) {
lazy[id] = value;
return;
}
// find the mid number
int mid = (l + r) / 2;
// check for pending updates
if (lazy[id])
lazy[2 * id] = lazy[2 * id + 1] = lazy[id];
// make lazy[id] = 0, so that it has no pending updates
lazy[id] = 0;
// call for two child nodes
update(x, y, value, 2 * id, l, mid);
update(x, y, value, 2 * id + 1, mid, r);
}
// Function to find non-zero integers in the range [l, r)
void query(int id, int l, int r)
{
// if id contains positive number
if (lazy[id]) {
se.insert(lazy[id]);
// There is no need to see the children,
// because all the interval have same number
return;
}
// check for out of bound
if (r - l < 2)
return;
// find the middle number
int mid = (l + r) / 2;
// call for two child nodes
query(2 * id, l, mid);
query(2 * id + 1, mid, r);
}
// Driver code
int main()
{
// size of the array and number of queries
int n = 5, q = 3;
// Update operation for l, r, x, id, 0, n
update(1, 4, 1, 1, 0, n);
update(0, 2, 2, 1, 0, n);
update(3, 4, 3, 1, 0, n);
// Query operation to get answer in the range [0, n-1]
query(1, 0, n);
// Print the count of non-zero elements
cout << se.size() << endl;
return 0;
}
Java
// Java implementation for above approach
import java.util.*;
class geeks
{
static int N = 100005;
// To store the tree in lazy propagation
static int[] lazy = new int[4*N];
// To store the different numbers
static Set se = new HashSet();
// Function to update in the range [x, y) with given value
public static void update(int x, int y, int value,
int id, int l, int r)
{
// check out of bound
if (x >= r || l >= y)
return;
// check for complete overlap
if (x <= l && r <= y)
{
lazy[id] = value;
return;
}
// find the mid number
int mid = (l + r) / 2;
// check for pending updates
if (lazy[id] != 0)
lazy[2 * id] = lazy[2 * id + 1] = lazy[id];
// make lazy[id] = 0, so that it has no pending updates
lazy[id] = 0;
// call for two child nodes
update(x, y, value, 2 * id, l, mid);
update(x, y, value, 2 * id + 1, mid, r);
}
// Function to find non-zero integers in the range [l, r)
public static void query(int id, int l, int r)
{
// if id contains positive number
if (lazy[id] != 0)
{
se.add(lazy[id]);
// There is no need to see the children,
// because all the interval have same number
return;
}
// check for out of bound
if (r - l < 2)
return;
// find the middle number
int mid = (l + r) / 2;
// call for two child nodes
query(2 * id, l, mid);
query(2 * id + 1, mid, r);
}
// Driver Code
public static void main(String[] args)
{
// size of the array and number of queries
int n = 5, q = 3;
// Update operation for l, r, x, id, 0, n
update(1, 4, 1, 1, 0, n);
update(0, 2, 2, 1, 0, n);
update(3, 4, 3, 1, 0, n);
// Query operation to get answer in the range [0, n-1]
query(1, 0, n);
// Print the count of non-zero elements
System.out.println(se.size());
}
}
// This code is contibuted by
// sanjeev2552
Python3
# Python3 implementation for above approach
N = 100005
# To store the tree in lazy propagation
lazy = [0] * (4 * N);
# To store the different numbers
se = set()
# Function to update in the range [x, y)
# with given value
def update(x, y, value, id, l, r) :
# check out of bound
if (x >= r or l >= y):
return;
# check for complete overlap
if (x <= l and r <= y) :
lazy[id] = value;
return;
# find the mid number
mid = (l + r) // 2;
# check for pending updates
if (lazy[id]) :
lazy[2 * id] = lazy[2 * id + 1] = lazy[id];
# make lazy[id] = 0,
# so that it has no pending updates
lazy[id] = 0;
# call for two child nodes
update(x, y, value, 2 * id, l, mid);
update(x, y, value, 2 * id + 1, mid, r);
# Function to find non-zero integers
# in the range [l, r)
def query(id, l, r) :
# if id contains positive number
if (lazy[id]) :
se.add(lazy[id]);
# There is no need to see the children,
# because all the interval have same number
return;
# check for out of bound
if (r - l < 2) :
return;
# find the middle number
mid = (l + r) // 2;
# call for two child nodes
query(2 * id, l, mid);
query(2 * id + 1, mid, r);
# Driver code
if __name__ == "__main__" :
# size of the array and number of queries
n = 5; q = 3;
# Update operation for l, r, x, id, 0, n
update(1, 4, 1, 1, 0, n);
update(0, 2, 2, 1, 0, n);
update(3, 4, 3, 1, 0, n);
# Query operation to get answer
# in the range [0, n-1]
query(1, 0, n);
# Print the count of non-zero elements
print(len(se));
# This code is contributed by AnkitRai01
C#
// C# implementation for above approach
using System;
using System.Collections.Generic;
public class geeks
{
static int N = 100005;
// To store the tree in lazy propagation
static int[] lazy = new int[4*N];
// To store the different numbers
static HashSet se = new HashSet();
// Function to update in the range [x, y) with given value
public static void update(int x, int y, int value,
int id, int l, int r)
{
// check out of bound
if (x >= r || l >= y)
return;
// check for complete overlap
if (x <= l && r <= y)
{
lazy[id] = value;
return;
}
// find the mid number
int mid = (l + r) / 2;
// check for pending updates
if (lazy[id] != 0)
lazy[2 * id] = lazy[2 * id + 1] = lazy[id];
// make lazy[id] = 0, so that it has no pending updates
lazy[id] = 0;
// call for two child nodes
update(x, y, value, 2 * id, l, mid);
update(x, y, value, 2 * id + 1, mid, r);
}
// Function to find non-zero integers in the range [l, r)
public static void query(int id, int l, int r)
{
// if id contains positive number
if (lazy[id] != 0)
{
se.Add(lazy[id]);
// There is no need to see the children,
// because all the interval have same number
return;
}
// check for out of bound
if (r - l < 2)
return;
// find the middle number
int mid = (l + r) / 2;
// call for two child nodes
query(2 * id, l, mid);
query(2 * id + 1, mid, r);
}
// Driver Code
public static void Main(String[] args)
{
// size of the array and number of queries
int n = 5, q = 3;
// Update operation for l, r, x, id, 0, n
update(1, 4, 1, 1, 0, n);
update(0, 2, 2, 1, 0, n);
update(3, 4, 3, 1, 0, n);
// Query operation to get answer in the range [0, n-1]
query(1, 0, n);
// Print the count of non-zero elements
Console.WriteLine(se.Count);
}
}
// This code is contributed by Rajput-Ji
3