Count of Distinct strings possible by inserting K characters in the original string

Given a string S and an integer K, the task is to find the total number of strings that can be formed by inserting exactly K characters at any position of the string S. Since the answer can be large, print it modulo 109+7.
Examples:

Input: S = “a” K = 1 
Output: 51 
Explanation: 
Since any of the 26 characters can be inserted at before ‘a’ or after ‘a’, a total of 52 possible strings can be formed. 
But the string “aa” gets formed twice. Hence count of distinct strings possible is 51.

Input: S = “abc” K = 2 
Output: 6376

Approach: 
The idea is to find the number of strings that contains the str as a subsequence. Follow the steps below to solve the problem:

  1. The total number of strings that can be formed by N characters is 26N.
  2. Calculate 26N using Binary Exponentiation.
  3. In this problem, only the strings that contain the str as a subsequence needs to be considered.
  4. Hence, the final count of strings is given by

    (total number of strings) – (number of strings that don’t contain the input string as a sub-sequence)



  5. While calculating such strings that don’t contain the str as a subsequence, observe that the length of the prefix of S is a subsequence of the resulting string can be between 0 to |S|-1.
  6. For every prefix length from 0 to |S|-1, find the total number of strings that can be formed with such a prefix as a sub-sequence. Then subtract that value from 26N.
  7. Hence, the final answer is:

    26^{N} - \sum_{i = 0}^{|S| - 1} \binom{N}{i}*25^{N - i}

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
#define int long long int
const int mod = 1e9 + 7;
  
// Function to calculate and return
// x^n in log(n) time using
// Binary Exponentiation
int binExp(int base, int power)
{
    int x = 1;
    while (power) {
        if (power % 2 == 1)
            x = ((x % mod)
                 * (base % mod))
                % mod;
  
        base = ((base % mod)
                * (base % mod))
               % mod;
        power = power / 2;
    }
    return x;
}
  
// Function to calculate the factorial
// of a number
int fact(int num)
{
    int result = 1;
  
    for (int i = 1; i <= num; ++i) {
  
        result = ((result % mod)
                  * (i % mod))
                 % mod;
    }
  
    return result;
}
  
// Function to calculate combination
int calculate_nCi(int N, int i)
{
    // nCi = ( n! ) / (( n-i )! * i!)
    int nfact = fact(N);
    int ifact = fact(i);
    int dfact = fact(N - i);
  
    // Using Euler's theorem of Modular
    // multiplicative inverse to find
    // the inverse of a number.
    // (1/a)%mod=a^(m?2)%mod
    int inv_ifact = binExp(ifact, mod - 2);
    int inv_dfact = binExp(dfact, mod - 2);
  
    int denm
        = ((inv_ifact % mod)
           * (inv_dfact % mod))
          % mod;
  
    int answer = ((nfact % mod)
                  * (denm % mod))
                 % mod;
    return answer;
}
  
// Function to find the count of
// possible strings
void countSubstring(int N, int s, int k)
{
    // Number of ways to form all
    // possible strings
    int allWays = binExp(26, N);
  
    // Number of ways to form strings
    // that don't contain the input
    // string as a subsequence
    int noWays = 0;
  
    // Checking for all prefix length
    // from 0 to |S|-1.
    for (int i = 0; i < s; ++i) {
        // to calculate nCi
        int nCi = calculate_nCi(N, i);
  
        // Select the remaining characters
        // 25 ^ (N-i)
        int remaining = binExp(25, N - i);
  
        int multiply
            = ((nCi % mod)
               * (remaining % mod))
              % mod;
  
        // Add the answer for this prefix
        // length to the final answer
        noWays = ((noWays % mod)
                  + (multiply % mod))
                 % mod;
    }
  
    // Answer is the difference of
    // allWays and noWays
    int answer = ((allWays % mod)
                  - (noWays % mod))
                 % mod;
  
    if (answer < 0)
        answer += mod;
  
    // Print the answer
    cout << answer;
}
  
// Driver Code
int32_t main()
{
    string str = "abc";
    int k = 2;
    int s = str.length();
  
    int N = s + k;
  
    countSubstring(N, s, k);
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
class GFG{
  
static final long mod = 1000000007;
  
// Function to calculate and return
// x^n in log(n) time using
// Binary Exponentiation
static long binExp(long base, long power)
{
    long x = 1;
    while (power != 0)
    {
        if (power % 2 == 1)
            x = ((x % mod) * 
              (base % mod)) % mod;
  
        base = ((base % mod) *
                (base % mod)) % mod;
        power = power / 2;
    }
    return x;
}
  
// Function to calculate the factorial
// of a number
static long fact(long num)
{
    long result = 1;
  
    for(long i = 1; i <= num; ++i) 
    {
        result = ((result % mod) * 
                       (i % mod)) % mod;
    }
    return result;
}
  
// Function to calculate combination
static long calculate_nCi(long N, long i)
{
      
    // nCi = ( n! ) / (( n-i )! * i!)
    long nfact = fact(N);
    long ifact = fact(i);
    long dfact = fact(N - i);
  
    // Using Euler's theorem of Modular
    // multiplicative inverse to find
    // the inverse of a number.
    // (1/a)%mod=a^(m?2)%mod
    long inv_ifact = binExp(ifact, mod - 2);
    long inv_dfact = binExp(dfact, mod - 2);
  
    long denm = ((inv_ifact % mod) * 
                 (inv_dfact % mod)) % mod;
  
    long answer = ((nfact % mod) *
                    (denm % mod)) % mod;
    return answer;
}
  
// Function to find the count of
// possible strings
static void countSubstring(long N, long s, long k)
{
      
    // Number of ways to form all
    // possible strings
    long allWays = binExp(26, N);
  
    // Number of ways to form strings
    // that don't contain the input
    // string as a subsequence
    long noWays = 0;
  
    // Checking for all prefix length
    // from 0 to |S|-1.
    for(long i = 0; i < s; ++i) 
    {
          
        // To calculate nCi
        long nCi = calculate_nCi(N, i);
  
        // Select the remaining characters
        // 25 ^ (N-i)
        long remaining = binExp(25, N - i);
  
        long multiply = ((nCi % mod) *
                   (remaining % mod)) % mod;
  
        // Add the answer for this prefix
        // length to the final answer
        noWays = ((noWays % mod) +
                (multiply % mod)) % mod;
    }
  
    // Answer is the difference of
    // allWays and noWays
    long answer = ((allWays % mod) - 
                    (noWays % mod)) % mod;
  
    if (answer < 0)
        answer += mod;
  
    // Print the answer
    System.out.println(answer);
}
      
// Driver code    
public static void main(String[] args) 
{
    String str = "abc";
    long k = 2;
    long s = str.length();
    long N = s + k;
      
    countSubstring(N, s, k);
}
}
  
// This code is contributed by rutvik_56

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for the above approach
mod = 1000000007
  
# Function to calculate and return
# x^n in log(n) time using
# Binary Exponentiation
def binExp(base, power):
  
    x = 1
    while (power):
        if (power % 2 == 1):
            x = (((x % mod) * 
               (base % mod)) % mod)
  
        base = (((base % mod) * 
                 (base % mod)) % mod)
        power = power // 2
      
    return x
  
# Function to calculate the factorial
# of a number
def fact(num):
  
    result = 1
  
    for i in range(1, num + 1):
        result = (((result % mod) * 
                        (i % mod)) % mod)
                          
    return result
  
# Function to calculate combination
def calculate_nCi(N, i):
  
    # nCi = ( n! ) / (( n-i )! * i!)
    nfact = fact(N)
    ifact = fact(i)
    dfact = fact(N - i)
  
    # Using Euler's theorem of Modular
    # multiplicative inverse to find
    # the inverse of a number.
    # (1/a)%mod=a^(m?2)%mod
    inv_ifact = binExp(ifact, mod - 2)
    inv_dfact = binExp(dfact, mod - 2)
  
    denm = (((inv_ifact % mod) * 
             (inv_dfact % mod)) % mod)
  
    answer = (((nfact % mod) * 
                (denm % mod)) % mod)
                  
    return answer
  
# Function to find the count of
# possible strings
def countSubstring(N, s, k):
  
    # Number of ways to form all
    # possible strings
    allWays = binExp(26, N)
  
    # Number of ways to form strings
    # that don't contain the input
    # string as a subsequence
    noWays = 0
  
    # Checking for all prefix length
    # from 0 to |S|-1.
    for i in range(s):
          
        # To calculate nCi
        nCi = calculate_nCi(N, i)
  
        # Select the remaining characters
        # 25 ^ (N-i)
        remaining = binExp(25, N - i)
  
        multiply = (((nCi % mod) * 
              (remaining % mod)) % mod)
  
        # Add the answer for this prefix
        # length to the final answer
        noWays =(((noWays % mod) + 
                (multiply % mod)) % mod)
      
    # Answer is the difference of
    # allWays and noWays
    answer = (((allWays % mod) - 
               (noWays % mod)) % mod)
  
    if (answer < 0):
        answer += mod
  
    # Print the answer
    print(answer)
  
# Driver Code
if __name__ == "__main__":
  
    st = "abc"
    k = 2
    s = len(st)
  
    N = s + k
  
    countSubstring(N, s, k)
  
# This code is contributed by chitranayal

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the above approach
using System;
  
class GFG{
  
static readonly long mod = 1000000007;
  
// Function to calculate and return
// x^n in log(n) time using
// Binary Exponentiation
static long binExp(long Base, long power)
{
    long x = 1;
    while (power != 0)
    {
        if (power % 2 == 1)
            x = ((x % mod) * 
              (Base % mod)) % mod;
  
        Base = ((Base % mod) *
                (Base % mod)) % mod;
        power = power / 2;
    }
    return x;
}
  
// Function to calculate the factorial
// of a number
static long fact(long num)
{
    long result = 1;
  
    for(long i = 1; i <= num; ++i) 
    {
        result = ((result % mod) * 
                       (i % mod)) % mod;
    }
    return result;
}
  
// Function to calculate combination
static long calculate_nCi(long N, long i)
{
    // nCi = ( n! ) / (( n-i )! * i!)
    long nfact = fact(N);
    long ifact = fact(i);
    long dfact = fact(N - i);
  
    // Using Euler's theorem of Modular
    // multiplicative inverse to find
    // the inverse of a number.
    // (1/a)%mod=a^(m?2)%mod
    long inv_ifact = binExp(ifact, mod - 2);
    long inv_dfact = binExp(dfact, mod - 2);
  
    long denm = ((inv_ifact % mod) * 
                 (inv_dfact % mod)) % mod;
  
    long answer = ((nfact % mod) *
                    (denm % mod)) % mod;
    return answer;
}
  
// Function to find the count of
// possible strings
static void countSubstring(long N, long s, long k)
{
      
    // Number of ways to form all
    // possible strings
    long allWays = binExp(26, N);
  
    // Number of ways to form strings
    // that don't contain the input
    // string as a subsequence
    long noWays = 0;
  
    // Checking for all prefix length
    // from 0 to |S|-1.
    for(long i = 0; i < s; ++i) 
    {
          
        // To calculate nCi
        long nCi = calculate_nCi(N, i);
  
        // Select the remaining characters
        // 25 ^ (N-i)
        long remaining = binExp(25, N - i);
  
        long multiply = ((nCi % mod) *
                   (remaining % mod)) % mod;
  
        // Add the answer for this prefix
        // length to the readonly answer
        noWays = ((noWays % mod) +
                (multiply % mod)) % mod;
    }
  
    // Answer is the difference of
    // allWays and noWays
    long answer = ((allWays % mod) - 
                    (noWays % mod)) % mod;
  
    if (answer < 0)
        answer += mod;
  
    // Print the answer
    Console.WriteLine(answer);
}
      
// Driver code 
public static void Main(String[] args) 
{
    String str = "abc";
    long k = 2;
    long s = str.Length;
    long N = s + k;
      
    countSubstring(N, s, k);
}
}
  
// This code is contributed by Rajput-Ji

chevron_right


Output: 

6376

Time Complexity: O(N), where N is the length of the given string. 
Auxiliary Space: O(1)
 

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.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.