Open In App

Find the final string after flipping bits at the indices that are multiple of prime factors of array elements

Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary string S of size N and an array arr[] of M integers, the task is to find the final string after flipping the characters at indices which are multiple of the prime factors of all the array elements. Note that this problem uses 1-based indexing.

Examples:

Input: S = “000000”, arr[] = {2, 4, 6}
Output: 011100
Explanation: 

  1. The prime factors of 2 are {2}. Therefore string after flipping the values of all the indices that are multiple of 2 is S = “010101”.
  2. The prime factors of 4 are {2}. Therefore string after flipping the values of all the indices that are multiple of 2 is S = “000000”.
  3. The prime factors of 6 are {2, 3}. Therefore string after flipping the values of all the indices that are multiple of 2 is S = “010101” and the string after flipping the values of all the indices that are multiple of 3 is S = “011100”.

Input: S = “001100”, arr[] = {2, 3, 5}
Output: 010010

Approach: The given problem can be solved with the help of the Sieve of Eratosthenes by storing the frequency of primes factors of all the array elements. It can be observed that the prime factors with even frequencies will not contribute to flipping. Therefore, the resultant string can be obtained by flipping the bits of indices that are multiple of prime factors with odd frequency. Follow the steps below to solve the given problem:

  • Create a function getFactorization(), which returns all the prime factors of any number.
  • Initialize an array, frequency[] that stores the frequency of all the distinct prime factors of all elements of the array arr[].
  • Traverse the given array arr[] and for each array element arr[i], find the prime factor of it using getFactorization( arr[i] ) and increment the frequency of the prime factors in the frequency[] array.
  • For all odd values of frequency[i] in the array, iterate through all the factors of i and flip the bits of respective indices in the given string S.
  • The string stored in S is the required string.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include "bits/stdc++.h"
using namespace std;
 
#define MAXN 100001
 
// Stores smallest prime factor
int spf[MAXN];
 
// Function to find the smallest prime
// factor for every number till MAXN
void sieve()
{
    spf[1] = 1;
 
    // Marking smallest prime factor for
    // every number to be itself
    for (int i = 2; i < MAXN; i++)
        spf[i] = i;
 
    // Separately marking spf for every
    // even number as 2
    for (int i = 4; i < MAXN; i += 2)
        spf[i] = 2;
 
    for (int i = 3; i * i < MAXN; i++) {
 
        // Checking if i is prime
        if (spf[i] == i) {
 
            // Marking SPF for all numbers
            // divisible by i
            for (int j = i * i;
                 j < MAXN; j += i) {
                if (spf[j] == j)
                    spf[j] = i;
            }
        }
    }
}
 
// Function to find all the distinct prime
// factors of the given number x
vector<int> getFactorization(int x)
{
    vector<int> ret;
 
    // Find the prime factors for X
    while (x != 1) {
 
        ret.push_back(spf[x]);
 
        // Find the spf[] of x
        int value = spf[x];
 
        while (x % value == 0)
            x = x / value;
    }
 
    // Return the prime factors for x
    return ret;
}
 
// Function to find string after flipping
// the characters at indices of prime
// factors of array elements arr[]
string flipString(string S, int arr[],
                  int M)
{
    // Precalculating Smallest Prime Factor
    sieve();
 
    // Stores the frequency of each
    // prime factor
    int frequency[MAXN] = { 0 };
 
    // Iterate over all elements of
    // the array arr[]
    for (int i = 0; i < M; i++) {
 
        // Stores prime factors of arr[i]
        vector<int> primeFactors
            = getFactorization(arr[i]);
 
        // Increment the frequency of all
        // prime factors of arr[i]
        for (auto& factors : primeFactors) {
            frequency[factors]++;
            frequency[factors] %= 2;
        }
    }
 
    int N = S.length();
 
    // Iterate over all elements of
    // the array frequency[]
    for (int i = 0; i < MAXN; i++) {
 
        // If frequency[i] is odd
        if (frequency[i] & 1) {
 
            // Flip bits of all indices
            // that are multiple of i
            for (int j = i; j <= N; j += i) {
                S[j - 1] = (S[j - 1]
                                    == '1'
                                ? '0'
                                : '1');
            }
        }
    }
 
    // Return Answer
    return S;
}
 
// Driver Code
int main()
{
    string S = "000000";
    int arr[] = { 2, 4, 6 };
    int M = sizeof(arr) / sizeof(arr[0]);
 
    cout << flipString(S, arr, M);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.ArrayList;
import java.util.Arrays;
 
class GFG {
 
    public static int MAXN = 100001;
 
    // Stores smallest prime factor
    public static int[] spf = new int[MAXN];
 
    // Function to find the smallest prime
    // factor for every number till MAXN
    public static void sieve() {
        spf[1] = 1;
 
        // Marking smallest prime factor for
        // every number to be itself
        for (int i = 2; i < MAXN; i++)
            spf[i] = i;
 
        // Separately marking spf for every
        // even number as 2
        for (int i = 4; i < MAXN; i += 2)
            spf[i] = 2;
 
        for (int i = 3; i * i < MAXN; i++) {
 
            // Checking if i is prime
            if (spf[i] == i) {
 
                // Marking SPF for all numbers
                // divisible by i
                for (int j = i * i; j < MAXN; j += i) {
                    if (spf[j] == j)
                        spf[j] = i;
                }
            }
        }
    }
 
    // Function to find all the distinct prime
    // factors of the given number x
    public static ArrayList<Integer> getFactorization(int x) {
        ArrayList<Integer> ret = new ArrayList<Integer>();
 
        // Find the prime factors for X
        while (x != 1) {
 
            ret.add(spf[x]);
 
            // Find the spf[] of x
            int value = spf[x];
 
            while (x % value == 0)
                x = x / value;
        }
 
        // Return the prime factors for x
        return ret;
    }
 
    // Function to find string after flipping
    // the characters at indices of prime
    // factors of array elements arr[]
    public static String flipString(String S, int arr[], int M) {
        // Precalculating Smallest Prime Factor
        sieve();
 
        // Stores the frequency of each
        // prime factor
        int[] frequency = new int[MAXN];
 
        Arrays.fill(frequency, 0);
 
        // Iterate over all elements of
        // the array arr[]
        for (int i = 0; i < M; i++) {
 
            // Stores prime factors of arr[i]
            ArrayList<Integer> primeFactors = getFactorization(arr[i]);
 
            // Increment the frequency of all
            // prime factors of arr[i]
            for (int factors : primeFactors) {
                frequency[factors]++;
                frequency[factors] %= 2;
            }
        }
 
        int N = S.length();
 
        // Iterate over all elements of
        // the array frequency[]
        for (int i = 0; i < MAXN; i++) {
 
            // If frequency[i] is odd
            if ((frequency[i] & 1) > 0) {
 
                // Flip bits of all indices
                // that are multiple of i
                for (int j = i; j <= N; j += i)
                {
                   
                    // S.replace(S.charAt(j - 1), (S.charAt(j - 1) == '1' ? '0' : '1'));
                    S = S.substring(0, j - 1) + (S.charAt(j - 1) == '1' ? '0' : '1') + S.substring(j);
                }
            }
        }
 
        // Return Answer
        return S;
    }
 
    // Driver Code
    public static void main(String args[]) {
        String S = "000000";
        int arr[] = { 2, 4, 6 };
        int M = arr.length;
 
        System.out.println(flipString(S, arr, M));
    }
}
 
// This code is contributed by gfgking.


Python3




# Python program for the above approach
MAXN = 100001
 
# Stores smallest prime factor
spf = [0] * MAXN
 
# Function to find the smallest prime
# factor for every number till MAXN
def sieve():
    spf[1] = 1
 
    # Marking smallest prime factor for
    # every number to be itself
    for i in range(2, MAXN):
        spf[i] = i
 
    # Separately marking spf for every
    # even number as 2
    for i in range(4, MAXN, 2):
        spf[i] = 2
 
    i = 3
    while(i * 8 < MAXN):
        i += 1
 
        # Checking if i is prime
        if (spf[i] == i):
 
            # Marking SPF for all numbers
            # divisible by i
            for j in range(i * i, MAXN, i):
                if (spf[j] == j):
                    spf[j] = i
         
 
# Function to find all the distinct prime
# factors of the given number x
def getFactorization (x):
    ret = []
 
    # Find the prime factors for X
    while (x != 1):
 
        ret.append(spf[x])
 
        # Find the spf[] of x
        value = spf[x]
 
        while (x % value == 0):
            x = x // value
 
    # Return the prime factors for x
    return ret
 
# Function to find string after flipping
# the characters at indices of prime
# factors of array elements arr[]
def flipString (S, arr, M):
 
    # Precalculating Smallest Prime Factor
    sieve();
 
    # Stores the frequency of each
    # prime factor
    frequency = [0] * MAXN
 
    # Iterate over all elements of
    # the array arr[]
    for i in range(0, M):
 
        # Stores prime factors of arr[i]
        primeFactors = getFactorization(arr[i])
 
        # Increment the frequency of all
        # prime factors of arr[i]
        for factors in primeFactors :
            frequency[factors] += 1
            frequency[factors] %= 2
         
 
    N = len(S)
 
    # Iterate over all elements of
    # the array frequency[]
    for i in range(0, MAXN):
 
        # If frequency[i] is odd
        if (frequency[i] & 1):
 
            # Flip bits of all indices
            # that are multiple of i
            for j in range(i, N + 1, i):
                S[j - 1] = ('0' if S[j - 1] == '1' else '1')
             
    # Return Answer
    return S
 
# Driver Code
S = "000000"
S = list(S)
arr = [2, 4, 6]
M = len(arr)
 
print("".join(flipString(S, arr, M)))
 
# This code is contributed by gfgking.


C#




// C# program for the above approach
 
using System;
using System.Collections.Generic;
 
class GFG
{
 
    public static int MAXN = 100001;
 
    // Stores smallest prime factor
    public static int[] spf = new int[MAXN];
 
    // Function to find the smallest prime
    // factor for every number till MAXN
    public static void sieve()
    {
        spf[1] = 1;
 
        // Marking smallest prime factor for
        // every number to be itself
        for (int i = 2; i < MAXN; i++)
            spf[i] = i;
 
        // Separately marking spf for every
        // even number as 2
        for (int i = 4; i < MAXN; i += 2)
            spf[i] = 2;
 
        for (int i = 3; i * i < MAXN; i++)
        {
 
            // Checking if i is prime
            if (spf[i] == i)
            {
 
                // Marking SPF for all numbers
                // divisible by i
                for (int j = i * i; j < MAXN; j += i)
                {
                    if (spf[j] == j)
                        spf[j] = i;
                }
            }
        }
    }
 
    // Function to find all the distinct prime
    // factors of the given number x
    public static List<int> getFactorization(int x)
    {
        List<int> ret = new List<int>();
 
        // Find the prime factors for X
        while (x != 1)
        {
 
            ret.Add(spf[x]);
 
            // Find the spf[] of x
            int value = spf[x];
 
            while (x % value == 0)
                x = x / value;
        }
 
        // Return the prime factors for x
        return ret;
    }
 
    // Function to find string after flipping
    // the characters at indices of prime
    // factors of array elements arr[]
    public static String flipString(String S, int[] arr, int M)
    {
        // Precalculating Smallest Prime Factor
        sieve();
 
        // Stores the frequency of each
        // prime factor
        int[] frequency = new int[MAXN];
 
        Array.Fill(frequency, 0);
 
        // Iterate over all elements of
        // the array arr[]
        for (int i = 0; i < M; i++)
        {
 
            // Stores prime factors of arr[i]
            List<int> primeFactors = getFactorization(arr[i]);
 
            // Increment the frequency of all
            // prime factors of arr[i]
            foreach (int factors in primeFactors)
            {
                frequency[factors]++;
                frequency[factors] %= 2;
            }
        }
 
        int N = S.Length;
 
        // Iterate over all elements of
        // the array frequency[]
        for (int i = 0; i < MAXN; i++)
        {
 
            // If frequency[i] is odd
            if ((frequency[i] & 1) > 0)
            {
 
                // Flip bits of all indices
                // that are multiple of i
                for (int j = i; j <= N; j += i)
                {
 
                    // S.replace(S.charAt(j - 1), (S.charAt(j - 1) == '1' ? '0' : '1'));
                    S = S.Substring(0, j - 1) + (S[j - 1] == '1' ? '0' : '1') + S.Substring(j);
                }
            }
        }
 
        // Return Answer
        return S;
    }
 
    // Driver Code
    public static void Main()
    {
        String S = "000000";
        int[] arr = { 2, 4, 6 };
        int M = arr.Length;
 
        Console.Write(flipString(S, arr, M));
    }
}
 
// This code is contributed by Saurabh Jaiswal


Javascript




<script>
    // JavaScript program for the above approach
 
    const MAXN = 100001;
 
    // Stores smallest prime factor
    let spf = new Array(MAXN).fill(0);
 
    // Function to find the smallest prime
    // factor for every number till MAXN
    const sieve = () => {
        spf[1] = 1;
 
        // Marking smallest prime factor for
        // every number to be itself
        for (let i = 2; i < MAXN; i++)
            spf[i] = i;
 
        // Separately marking spf for every
        // even number as 2
        for (let i = 4; i < MAXN; i += 2)
            spf[i] = 2;
 
        for (let i = 3; i * i < MAXN; i++) {
 
            // Checking if i is prime
            if (spf[i] == i) {
 
                // Marking SPF for all numbers
                // divisible by i
                for (let j = i * i;
                    j < MAXN; j += i) {
                    if (spf[j] == j)
                        spf[j] = i;
                }
            }
        }
    }
 
    // Function to find all the distinct prime
    // factors of the given number x
    const getFactorization = (x) => {
        let ret = [];
 
        // Find the prime factors for X
        while (x != 1) {
 
            ret.push(spf[x]);
 
            // Find the spf[] of x
            let value = spf[x];
 
            while (x % value == 0)
                x = parseInt(x / value);
        }
 
        // Return the prime factors for x
        return ret;
    }
 
    // Function to find string after flipping
    // the characters at indices of prime
    // factors of array elements arr[]
    const flipString = (S, arr, M) => {
 
        // Precalculating Smallest Prime Factor
        sieve();
 
        // Stores the frequency of each
        // prime factor
        let frequency = new Array(MAXN).fill(0);
 
        // Iterate over all elements of
        // the array arr[]
        for (let i = 0; i < M; i++) {
 
            // Stores prime factors of arr[i]
            let primeFactors = getFactorization(arr[i]);
 
            // Increment the frequency of all
            // prime factors of arr[i]
            for (let factors in primeFactors) {
                frequency[primeFactors[factors]]++;
                frequency[factors] %= 2;
            }
        }
 
        let N = S.length;
 
        // Iterate over all elements of
        // the array frequency[]
        for (let i = 0; i < MAXN; i++) {
 
            // If frequency[i] is odd
            if (frequency[i] & 1) {
 
                // Flip bits of all indices
                // that are multiple of i
                for (let j = i; j <= N; j += i) {
                    S[j - 1] = (S[j - 1] == '1' ? '0' : '1');
                }
            }
        }
        // Return Answer
        return S;
    }
 
    // Driver Code
 
    let S = "000000";
    S = S.split("");
    let arr = [2, 4, 6];
    let M = arr.length;
 
    document.write(flipString(S, arr, M).join(''));
 
    // This code is contributed by rakeshsahni
</script>


 
 

Output: 

011100

 

 

Time Complexity: O(N*log N + K*log K), where K is the maximum integer in the array arr[].
Auxiliary Space: O(K)

 



Last Updated : 30 Nov, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads