📌  相关文章
📜  应用给定操作q次后,找到数组中不同数字的数量

📅  最后修改于: 2021-04-17 11:40:08             🧑  作者: Mango

给定大小为N的数组,最初仅由零组成。任务是应用给定的操作q次,并找到数组中除零以外的其他数字的数量。

操作格式:update(l,r,x)::全部更新a [i] = x(l <= i <= r)。

例子:

方法 :
每个操作都会建议范围更新,因此请尝试使用延迟传播来更新阵列。使用惰性传播将操作执行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