Skip to content
Related Articles

Related Articles

Improve Article

Count of N-length binary strings that are repeated concatenations of a substring

  • Last Updated : 23 Aug, 2021

Given a positive integer N, the task is to find the number of binary strings of length N that are repeated concatenation of only one substring of that string.

Examples:

Input: N = 4
Output: 4
Explanation:
Below are the possible binary string of length N(= 4):

  1. “0000”: This string is the repeated concatenation of the substring “0”.
  2. “1111”: This string is the repeated concatenation of the substring “1”.
  3. “0101”: This string is the repeated concatenation of the substring “01”.
  4. “1010”: This string is the repeated concatenation of the substring “10”.

Therefore, the total count of such string is 4. Hence, print 4.

Input: N = 10
Output: 34



Approach: The given problem can be solved based on the observation that every possible string has a repeated substring which concatenated say K times, then the given length of string N must be divisible by K to generate all the resultant string.

Therefore, find all possible divisors of N and for each divisor, say K find the count of all possible strings it can form whose concatenation is the resultant string and this count can be calculated by 2K. Now, the number of strings that are repeated among them must also be subtracted, So perform the same operation on the divisor K and subtract it from 2K to get the total count for each recursive call.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include<bits/stdc++.h>
using namespace std;
 
// Store the recurring recursive states
map<int, int> dp;
 
// Function to find the number of
// strings of length N such that it
// is a concatenation it substrings
int countStrings(int N)
{
     
    // Single character cant be repeated
    if (N == 1)
        return 0;
     
    // Check if this state has been
    // already calculated
    if (dp.find(N) != dp.end())
        return dp[N];
     
    // Stores the resultant count for
    // the current recursive calls
    int ret = 0;
     
    // Iterate over all divisors
    for(int div = 1; div <= sqrt(N); div++)
    {
        if (N % div == 0)
        {
             
            // Non-Repeated = Total - Repeated
            ret += (1 << div) -  countStrings(div);
             
            int div2 = N/div;
             
            if (div2 != div and div != 1)
                 
                // Non-Repeated = Total - Repeated
                ret += (1 << div2) -  countStrings(div2);
        }
    }
     
    // Store the result for the
    // further calculation
    dp[N] = ret;       
                 
    // Return resultant count
    return ret;
}
 
// Driver code
int main()
{
    int N = 6;
     
    // Function Call
    cout << countStrings(N) << endl;
}
 
// This code is contributed by ipg2016107

Java




// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Store the recurring recursive states
static HashMap<Integer,
               Integer> dp = new HashMap<Integer,
                                         Integer>();
 
// Function to find the number of
// strings of length N such that it
// is a concatenation it substrings
static int countStrings(int N)
{
     
    // Single character cant be repeated
    if (N == 1)
        return 0;
     
    // Check if this state has been
    // already calculated
    if (dp.containsKey(N))
        return dp.get(N);
     
    // Stores the resultant count for
    // the current recursive calls
    int ret = 0;
     
    // Iterate over all divisors
    for(int div = 1; div <= Math.sqrt(N); div++)
    {
        if (N % div == 0)
        {
             
            // Non-Repeated = Total - Repeated
            ret += (1 << div) -  countStrings(div);
             
            int div2 = N / div;
             
            if (div2 != div && div != 1)
                 
                // Non-Repeated = Total - Repeated
                ret += (1 << div2) -  countStrings(div2);
        }
    }
     
    // Store the result for the
    // further calculation
    dp.put(N, ret);       
                 
    // Return resultant count
    return ret;
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 6;
     
    // Function Call
    System.out.print(countStrings(N));
}
}
 
// This code is contributed by code_hunt

Python3




# Python program for the above approach
 
# Store the recurring recursive states
dp = {}
 
# Function to find the number of
# strings of length N such that it
# is a concatenation it substrings
def countStrings(N):
    
    # Single character cant be repeated
    if N == 1:
        return 0
     
    # Check if this state has been
    # already calculated
    if dp.get(N, -1) != -1:
        return dp[N]
     
    # Stores the resultant count for
    # the current recursive calls
    ret = 0
     
    # Iterate over all divisors
    for div in range(1, int(N**.5)+1): 
        if N % div == 0:
             
            # Non-Repeated = Total - Repeated
            ret += (1 << div) -  countStrings(div)
             
            div2 = N//div
             
            if div2 != div and div != 1:
                 
                # Non-Repeated = Total - Repeated
                ret += (1 << div2) -  countStrings(div2)
     
    # Store the result for the
    # further calculation
    dp[N] = ret         
                 
    # Return resultant count
    return ret
 
# Driver Code
N = 6
 
# Function Call
print(countStrings(N))

C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Store the recurring recursive states
static Dictionary<int, int> dp = new Dictionary<int, int>();
 
// Function to find the number of
// strings of length N such that it
// is a concatenation it substrings
static int countStrings(int N)
{
     
    // Single character cant be repeated
    if (N == 1)
        return 0;
     
    // Check if this state has been
    // already calculated
    if (dp.ContainsKey(N))
        return dp[N];
     
    // Stores the resultant count for
    // the current recursive calls
    int ret = 0;
     
    // Iterate over all divisors
    for(int div = 1; div <= Math.Sqrt(N); div++)
    {
        if (N % div == 0)
        {
             
            // Non-Repeated = Total - Repeated
            ret += (1 << div) -  countStrings(div);
             
            int div2 = N / div;
             
            if (div2 != div && div != 1)
                 
                // Non-Repeated = Total - Repeated
                ret += (1 << div2) -  countStrings(div2);
        }
    }
     
    // Store the result for the
    // further calculation
    dp[N] = ret;     
                 
    // Return resultant count
    return ret;
}
 
// Driver Code
public static void Main()
{
    int N = 6;
     
    // Function Call
    Console.Write(countStrings(N));
}
}
 
// This code is contributed by splevel62.

Javascript




<script>
 
// JavaScript program for the above approach
 
// Store the recurring recursive states
let dp = new Map();
 
// Function to find the number of
// strings of length N such that it
// is a concatenation it substrings
function countStrings(N) {
  // Single character cant be repeated
  if (N == 1) return 0;
 
  // Check if this state has been
  // already calculated
  if (dp.has(N)) return dp.get(N);
 
  // Stores the resultant count for
  // the current recursive calls
  let ret = 0;
 
  // Iterate over all divisors
  for (let div = 1; div <= Math.sqrt(N); div++) {
    if (N % div == 0) {
      // Non-Repeated = Total - Repeated
      ret += (1 << div) - countStrings(div);
 
      let div2 = N / div;
 
      if (div2 != div && div != 1)
        // Non-Repeated = Total - Repeated
        ret += (1 << div2) - countStrings(div2);
    }
  }
 
  // Store the result for the
  // further calculation
  dp[N] = ret;
 
  // Return resultant count
  return ret;
}
 
// Driver code
 
let N = 6;
 
// Function Call
document.write(countStrings(N) + "<br>");
 
// This code is contributed by _saurabh_jaiswal
 
</script>
Output: 
10

 

Time Complexity: O(N)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :