Número de subarreglos que tienen una suma de la forma k^m, m >= 0

Dado un entero k y una array arr[] , la tarea es contar el número de sub-arrays que tienen la suma igual a alguna potencia integral positiva de k.
Ejemplos: 

Entrada: arr[] = { 2, 2, 2, 2 } K = 2 
Salida:
Sub-arrays con los siguientes índices son válidas: 
[1, 1], [2, 2], [3, 3], [4 , 4], [1, 2], 
[2, 3], [3, 4], [1, 4]
Entrada: arr[] = { 3, -6, -3, 12 } K = -3 
Salida:

Enfoque ingenuo : un enfoque ingenuo consiste en atravesar todos los subconjuntos y verificar para cada subconjunto si su suma es igual a alguna potencia integral de k.
Enfoque eficiente : un mejor enfoque es mantener una array de suma de prefijos prefix_sum y un mapa m que asigna una suma de prefijos a su cuenta. m[a] = 1 significa que a es la suma de un prefijo de algún prefijo. 

Itere a través de la array en dirección hacia atrás y siga cuidadosamente la discusión a continuación. Considere que mientras recorremos la array estamos en el i -ésimo índice y después de recorrer un índice realizamos la operación op = m[prefix_sum[i]]++ . Por lo tanto, cuando estamos en el índice i , la operación aún no se ha realizado. Vea el código para una explicación vívida.
Si m[a + b] = c donde a = prefix_sum[i], b = k p y c es el valor obtenido del mapa , entonces significa que a partir del i -ésimo índice hasta el final de la array, hay c sub-arrays cuya suma es igual a b. Agregue c a la suma actual. 
Esto se debe a que para cada índice j > i, se ha realizado m[prefix_sum[j]]++ . Por lo tanto, el mapa tiene información sobre las sumas de prefijos de prefijos que terminan en j > i . Al sumar b al prefijo sum podemos obtener el conteo de todas esas sumas a + b lo que indicará que existe un subarreglo que tiene suma igual a b

Nota : k = 1 y k = -1 deben manejarse por separado.
A continuación se muestra la implementación del enfoque anterior:  

C++

// C++ implementation of the above approach
#include <bits/stdc++.h>
 
#define ll long long
#define MAX 100005
 
using namespace std;
 
// Function to count number of sub-arrays
// whose sum is k^p where p>=0
ll countSubarrays(int* arr, int n, int k)
{
    ll prefix_sum[MAX];
    prefix_sum[0] = 0;
 
    partial_sum(arr, arr + n, prefix_sum + 1);
 
    ll sum;
 
    if (k == 1) {
 
        sum = 0;
        map<ll, int> m;
 
        for (int i = n; i >= 0; i--) {
 
            // If m[a+b] = c, then add c to the current sum.
            if (m.find(prefix_sum[i] + 1) != m.end())
                sum += m[prefix_sum[i] + 1];
 
            // Increase count of prefix sum.
            m[prefix_sum[i]]++;
        }
 
        return sum;
    }
 
    if (k == -1) {
 
        sum = 0;
        map<ll, int> m;
 
        for (int i = n; i >= 0; i--) {
 
            // If m[a+b] = c, then add c to the current sum.
            if (m.find(prefix_sum[i] + 1) != m.end())
                sum += m[prefix_sum[i] + 1];
 
            if (m.find(prefix_sum[i] - 1) != m.end())
                sum += m[prefix_sum[i] - 1];
 
            // Increase count of prefix sum.
            m[prefix_sum[i]]++;
        }
 
        return sum;
    }
 
    sum = 0;
 
    // b = k^p, p>=0
    ll b;
    map<ll, int> m;
 
    for (int i = n; i >= 0; i--) {
 
        b = 1;
        while (true) {
 
            // k^m can be maximum equal to 10^14.
            if (b > 100000000000000)
                break;
 
            // If m[a+b] = c, then add c to the current sum.
            if (m.find(prefix_sum[i] + b) != m.end())
                sum += m[prefix_sum[i] + b];
 
            b *= k;
        }
 
        // Increase count of prefix sum.
        m[prefix_sum[i]]++;
    }
 
    return sum;
}
 
// Driver code
int main()
{
    int arr[] = { 2, 2, 2, 2 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 2;
 
    cout << countSubarrays(arr, n, k);
 
    return 0;
}

Java

// Java implementation of the
// above approach
import java.util.*;
class GFG{
 
static final int MAX = 100005;
   
// partial_sum
static long[] partial_sum(long []prefix_sum,
                          int[]arr, int n)
{
  for (int i = 1; i <= n; i++)
  {
    prefix_sum[i] = (prefix_sum[i - 1] +
                     arr[i - 1]);
  }
 
  return prefix_sum;
}
   
// Function to count number of
// sub-arrays whose sum is k^p
// where p>=0
static int countSubarrays(int []arr,
                          int n, int k)
{
  long []prefix_sum = new long[MAX];
  prefix_sum[0] = 0;
  prefix_sum = partial_sum(prefix_sum ,
                           arr, n);
  int sum;
 
  if (k == 1)
  {
    sum = 0;
    HashMap<Long,
            Integer> m = new HashMap<>();
 
    for (int i = n; i >= 0; i--)
    {
      // If m[a+b] = c, then add c to
      // the current sum.
      if (m.containsKey(prefix_sum[i] + 1))
        sum += m.get(prefix_sum[i] + 1);
 
      // Increase count of prefix sum.
      if(m.containsKey(prefix_sum[i]))
        m.put(prefix_sum[i],
        m.get(prefix_sum[i]) + 1);
      else
        m.put(prefix_sum[i], 1);
    }
    return sum;
  }
 
  if (k == -1)
  {
    sum = 0;
    HashMap<Long,
            Integer> m = new HashMap<>();
 
    for (int i = n; i >= 0; i--)
    {
      // If m[a+b] = c, then add c to
      // the current sum.
      if (m.containsKey(prefix_sum[i] + 1))
        sum += m.get(prefix_sum[i] + 1);
 
      if (m.containsKey(prefix_sum[i] - 1))
        sum += m.get(prefix_sum[i] - 1);
 
      // Increase count of prefix sum.
      if(m.containsKey(prefix_sum[i]))
        m.put(prefix_sum[i],
        m.get(prefix_sum[i]) + 1);
      else
        m.put(prefix_sum[i], 1);
    }
    return sum;
  }
 
  sum = 0;
 
  // b = k^p, p>=0
  long b, l = 100000000000000L;
  HashMap<Long,
          Integer> m = new HashMap<>();
 
  for (int i = n; i >= 0; i--)
  {
    b = 1;
    while (true)
    {
      // k^m can be maximum equal
      // to 10^14.
      if (b > l)
        break;
 
      // If m[a+b] = c, then add c to
      // the current sum.
      if (m.containsKey(prefix_sum[i] + b))
        sum += m.get(prefix_sum[i] + b);
 
      b *= k;
    }
 
    // Increase count of prefix sum.
    if(m.containsKey(prefix_sum[i]))
      m.put((prefix_sum[i]),
      m.get(prefix_sum[i]) + 1);
    else
      m.put((prefix_sum[i]), 1);
  }
  return sum;
}
 
// Driver code
public static void main(String[] args)
{
  int arr[] = {2, 2, 2, 2};
  int n = arr.length;
  int k = 2;
  System.out.print(countSubarrays(arr,
                                  n, k));
}
}
 
// This code is contributed by Rajput-Ji

Python3

# Python3 implementation of
# the above approach
from collections import defaultdict
MAX = 100005
 
def partial_sum(prefix_sum,
                arr, n):
   
  for i in range(1 , n + 1):
    prefix_sum[i] = (prefix_sum[i - 1] +
                     arr[i - 1])
  return prefix_sum
     
# Function to count number of
# sub-arrays whose sum is k^p
# where p>=0
def countSubarrays(arr, n, k):
 
    prefix_sum = [0] * MAX
    prefix_sum[0] = 0
      
    prefix_sum = partial_sum(prefix_sum,
                             arr, n)
    if (k == 1):
        sum = 0
        m = defaultdict(int)
 
        for i in range(n, -1, -1):
 
            # If m[a+b] = c, then add
            # c to the current sum.
            if ((prefix_sum[i] + 1) in m):
                sum += m[prefix_sum[i] + 1]
 
            # Increase count of prefix sum.
            m[prefix_sum[i]] += 1
 
        return sum
 
    if (k == -1):
        sum = 0
        m = defaultdict(int)
 
        for i in range(n, -1, -1):
 
            # If m[a+b] = c, then add c
            # to the current sum.
            if ((prefix_sum[i] + 1) in m):
                sum += m[prefix_sum[i] + 1]
 
            if ((prefix_sum[i] - 1) in m):
                sum += m[prefix_sum[i] - 1]
 
            # Increase count of prefix sum.
            m[prefix_sum[i]] += 1
 
        return sum
 
    sum = 0
 
    # b = k^p, p>=0
    m = defaultdict(int)
 
    for i in range(n, -1, -1):
        b = 1
        while (True):
 
            # k^m can be maximum equal
            # to 10^14.
            if (b > 100000000000000):
                break
 
            # If m[a+b] = c, then add c
            # to the current sum.
            if ((prefix_sum[i] + b) in m):
                sum += m[prefix_sum[i] + b]
 
            b *= k
 
        # Increase count of prefix
        # sum.
        m[prefix_sum[i]] += 1
    return sum
 
# Driver code
if __name__ == "__main__":
 
    arr = [2, 2, 2, 2]
    n = len(arr)
    k = 2
    print(countSubarrays(arr, n, k))
 
# This code is contributed by Chitranayal

C#

// C# implementation of the
// above approach
using System;
using System.Collections.Generic;
class GFG{
 
static readonly int MAX = 100005;
   
// partial_sum
static long[] partial_sum(long []prefix_sum,
                          int[]arr, int n)
{
  for (int i = 1; i <= n; i++)
  {
    prefix_sum[i] = (prefix_sum[i - 1] +
                     arr[i - 1]);
  }
 
  return prefix_sum;
}
   
// Function to count number of
// sub-arrays whose sum is k^p
// where p>=0
static int countSubarrays(int []arr,
                          int n, int k)
{
  long []prefix_sum = new long[MAX];
  prefix_sum[0] = 0;
  prefix_sum = partial_sum(prefix_sum ,
                           arr, n);
  int sum;
 
  if (k == 1)
  {
    sum = 0;
    Dictionary<long,
               int> mp =
               new Dictionary<long,
                              int>();
 
    for (int i = n; i >= 0; i--)
    {
      // If m[a+b] = c, then add c to
      // the current sum.
      if (mp.ContainsKey(prefix_sum[i] + 1))
        sum += mp[prefix_sum[i] + 1];
 
      // Increase count of prefix sum.
      if(mp.ContainsKey(prefix_sum[i]))
        mp.Add(prefix_sum[i],
        mp[prefix_sum[i]] + 1);
      else
        mp.Add(prefix_sum[i], 1);
    }
    return sum;
  }
 
  if (k == -1)
  {
    sum = 0;
    Dictionary<long,
               int> map =
               new Dictionary<long,
                              int>();
 
    for (int i = n; i >= 0; i--)
    {
      // If m[a+b] = c, then add c to
      // the current sum.
      if (map.ContainsKey(prefix_sum[i] + 1))
        sum += map[prefix_sum[i] + 1];
 
      if (map.ContainsKey(prefix_sum[i] - 1))
        sum += map[prefix_sum[i] - 1];
 
      // Increase count of prefix sum.
      if(map.ContainsKey(prefix_sum[i]))
        map.Add(prefix_sum[i],
        map[prefix_sum[i]] + 1);
      else
        map.Add(prefix_sum[i], 1);
    }
    return sum;
  }
 
  sum = 0;
 
  // b = k^p, p>=0
  long b, l = 100000000000000L;
  Dictionary<long,
             int> m =
             new Dictionary<long,
                            int>();
 
  for (int i = n; i >= 0; i--)
  {
    b = 1;
    while (true)
    {
      // k^m can be maximum equal
      // to 10^14.
      if (b > l)
        break;
 
      // If m[a+b] = c, then add c to
      // the current sum.
      if (m.ContainsKey(prefix_sum[i] + b))
        sum += m[prefix_sum[i] + b];
 
      b *= k;
    }
 
    // Increase count of prefix sum.
    if(m.ContainsKey(prefix_sum[i]))
      m.Add((prefix_sum[i]),
      m[prefix_sum[i]] + 1);
    else
      m.Add((prefix_sum[i]), 1);
  }
  return sum;
}
 
// Driver code
public static void Main(String[] args)
{
  int []arr = {2, 2, 2, 2};
  int n = arr.Length;
  int k = 2;
  Console.Write(countSubarrays(arr,
                               n, k));
}
}
 
// This code is contributed by shikhasingrajput

Javascript

<script>
 
// JavaScript implementation of the
// above approach
 
let MAX = 100005;
 
// partial_sum
function partial_sum(prefix_sum,arr,n)
{
    for (let i = 1; i <= n; i++)
  {
    prefix_sum[i] = (prefix_sum[i - 1] +
                     arr[i - 1]);
  }
  
  return prefix_sum;
}
 
// Function to count number of
// sub-arrays whose sum is k^p
// where p>=0
function countSubarrays(arr,n,k)
{
    let prefix_sum = new Array(MAX);
  prefix_sum[0] = 0;
  prefix_sum = partial_sum(prefix_sum ,
                           arr, n);
  let sum;
  
  if (k == 1)
  {
    sum = 0;
    let m = new Map();
  
    for (let i = n; i >= 0; i--)
    {
      // If m[a+b] = c, then add c to
      // the current sum.
      if (m.has(prefix_sum[i] + 1))
        sum += m.get(prefix_sum[i] + 1);
  
      // Increase count of prefix sum.
      if(m.has(prefix_sum[i]))
        m.set(prefix_sum[i],
        m.get(prefix_sum[i]) + 1);
      else
        m.set(prefix_sum[i], 1);
    }
    return sum;
  }
  
  if (k == -1)
  {
    sum = 0;
    let m = new Map();
  
    for (let i = n; i >= 0; i--)
    {
      // If m[a+b] = c, then add c to
      // the current sum.
      if (m.has(prefix_sum[i] + 1))
        sum += m.get(prefix_sum[i] + 1);
  
      if (m.has(prefix_sum[i] - 1))
        sum += m.get(prefix_sum[i] - 1);
  
      // Increase count of prefix sum.
      if(m.has(prefix_sum[i]))
        m.set(prefix_sum[i],
        m.get(prefix_sum[i]) + 1);
      else
        m.set(prefix_sum[i], 1);
    }
    return sum;
  }
  
  sum = 0;
  
  // b = k^p, p>=0
  let b, l = 100000000000000;
  let m = new Map();
  
  for (let i = n; i >= 0; i--)
  {
    b = 1;
    while (true)
    {
      // k^m can be maximum equal
      // to 10^14.
      if (b > l)
        break;
  
      // If m[a+b] = c, then add c to
      // the current sum.
      if (m.has(prefix_sum[i] + b))
        sum += m.get(prefix_sum[i] + b);
  
      b *= k;
    }
  
    // Increase count of prefix sum.
    if(m.has(prefix_sum[i]))
      m.set((prefix_sum[i]),
      m.get(prefix_sum[i]) + 1);
    else
      m.set((prefix_sum[i]), 1);
  }
  return sum;
}
 
// Driver code
let arr=[2, 2, 2, 2];
let n = arr.length;
let k = 2;
document.write(countSubarrays(arr,
                                  n, k));
 
 
// This code is contributed by avanitrachhadiya2155
 
</script>
Producción: 

8

 

Publicación traducida automáticamente

Artículo escrito por rohan23chhabra y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *