Suppose we are provided with a string str. A border of a string is a substring that is a proper prefix and a suffix of that string. For example, 'ab' is a border of the string 'ababab'. A border is called a palindrome border if the border string is a palindrome. Now suppose there is f(str) number of palindrome borders in the given string str. We have to find out the sum of f(str_k) for all non-empty substrings str_k of str. The sum can be large, so a modulo operation can be performed by 10^9 + 7.
So, if the input is like str = 'pqpqp', then the output will be 5 There exists 15 substrings of the string 'pqpqp'; however only 4 substrings have palindromic borders. The strings are:
pqp : f(pqp) = 1 pqpqp : f(pqpqp) = 2 qpq : f(qpq) = 1 pqp : f(pqp) = 1 The sum of these values are 1 + 2 + 1 + 1 = 5.
To solve this, we will follow these steps −
- Define a function palindrome_calculator() . This will take input_dict
- ans := 0
- for each item1, item2 in the values of input_dict, do
- ans := ans + item2 *(floor value of (item2 - 1) / 2)
- return ans
- Define a function str_check() . This will take string
- t_str := string[0]
- for each s in string, do
- if s is not same as t_str, then
- return False
- return True
- if s is not same as t_str, then
- Define a function string_res() . This will take string
- ans := 0
- for i in range 2 to size of string + 1, do
- ans := ans + i *(floor value of (i - 1) / 2)
- ans := ans mod 1000000007
- return and
- if str_check(string) is True, then
- return string_res(string)
- ans := 0
- odd_list := a new list containing a new list, a new map, and 1
- for each s in string, do
- if s is not present in odd_list[1], then
- odd_list[1, s] := 0
- odd_list[1, s] := odd_list[1, s] + 1
- if s is not present in odd_list[1], then
- for i in range 0 to size of string, do
- insert i at the end of odd_list[0]
- ans := ans + palindrome_calculator(odd_list[1])
- even_list := a new list containing a new list, a new map, and 1
- for i in range 0 to size of string - 1, do
- if string[i] is same as string[i + 1], then
- insert i at the end of even_list[0]
- tmp := string[from index i to i + 2]
- if tmp is not present in even_list[1], then
- even_list[1, tmp] := 0
- even_list[1, tmp] := even_list[1, tmp] + 1
- if string[i] is same as string[i + 1], then
- ans := ans + palindrome_calculator(even_list[1])
- for val in range 3 to size of string, do
- if val mod 2 is same as 0, then
- wt := even_list
- otherwise,
- wt := odd_list
- new_t := a new list containing a new list, a new map, and val
- for each index in wt[0], do
- if index - 1 >= 0 and index + val - 2 < size of string and string[index - 1] is same as string[index + val - 2], then
- insert index - 1 at the end of new_t[0]
- tmp := string[from index index - 1 to index - 1 + val]
- if tmp is not present in new_t[1], then
- new_t[1, tmp] := 0
- new_t[1, tmp] := new_t[1, tmp] + 1
- if index - 1 >= 0 and index + val - 2 < size of string and string[index - 1] is same as string[index + val - 2], then
- ans := ans + palindrome_calculator(new_t[1])
- ans := ans mod 1000000007
- if val mod 2 is same as 0, then
- even_list := new_t
- otherwise,
- odd_list := new_t
- if val mod 2 is same as 0, then
- return ans
Example
Let us see the following implementation to get better understanding
def palindrome_calculator(input_dict): ans = 0 for item1, item2 in input_dict.items(): ans += item2 * (item2 - 1) // 2 return ans def str_check(string): t_str = string[0] for s in string: if s != t_str: return False return True def string_res(string): ans = 0 for i in range(2, len(string) + 1): ans += i * (i - 1) // 2 ans %= 1000000007 return ans def solve(string): if str_check(string): return string_res(string) ans = 0 odd_list = [[], {}, 1] for s in string: if s not in odd_list[1]: odd_list[1][s] = 0 odd_list[1][s] += 1 for i in range(len(string)): odd_list[0].append(i) ans += palindrome_calculator(odd_list[1]) even_list = [[], {}, 1] for i in range(len(string) - 1): if string[i] == string[i + 1]: even_list[0].append(i) tmp = string[i:i + 2] if tmp not in even_list[1]: even_list[1][tmp] = 0 even_list[1][tmp] += 1 ans += palindrome_calculator(even_list[1]) for val in range(3, len(string)): if val % 2 == 0: wt = even_list else: wt = odd_list new_t = [[], {}, val] for index in wt[0]: if index - 1 >= 0 and index + val - 2 < len(string) and string[index - 1] == string[index + val - 2]: new_t[0].append(index - 1) tmp = string[index - 1 : index - 1 + val] if tmp not in new_t[1]: new_t[1][tmp] = 0 new_t[1][tmp] += 1 ans += palindrome_calculator(new_t[1]) ans %= 1000000007 if val % 2 == 0: even_list = new_t else: odd_list = new_t return ans print(solve('pqpqp'))
Input
'pqpqp'
Output
5