# Queries on substring palindrome formation

Last Updated : 12 Sep, 2023

Given a string S, and two types of queries.

```Type 1: 1 L x, Indicates update Lth index
of string S by x character.
Type 2: 2 L R, Find if characters between position L and R
of string, S can form a palindrome string.
If palindrome can be formed print "Yes",
else print "No".
1 <= L, R <= |S| ```

Examples:

```Input : S = "geeksforgeeks"
Query 1: 1 4 g
Query 2: 2 1 4
Query 3: 2 2 3
Query 4: 1 10 t
Query 5: 2 10 11
Output :
Yes
Yes
No

Query 1: update index 3 (position 4) of string S by
character 'g'. So new string S = "geegsforgeeks".

Query 2: find if rearrangement between index 0 and 3
can form a palindrome. "geegs" is palindrome, print "Yes".

Query 3: find if rearrangement between index 1 and 2
can form a palindrome. "ee" is palindrome, print "Yes".

Query 4: update index 9 (position 10) of string S by
character 't'. So new string S = "geegsforgteks".

Query 3: find if rearrangement between index 9 and 10
can form a palindrome. "te" is not palindrome, print "No".```

Substring S[L…R] form a palindrome only if frequencies of all the characters in S[L…R] are even, with one except allowed.

```For query of type 1, simply update string
S[L] by character x.

For each query of type 2, calculate the
frequency of character and check if
frequencies of all characters is even (with)
one exception allowed.```

Following are two different methods to find the frequency of each character in S[L…R]:

Method 1: Use a frequency array to find the frequency of each element in S[L…R].

Below is the implementation of this approach:

## C++

 `// C++ program to Queries on substring palindrome ` `// formation. ` `#include ` `using` `namespace` `std; ` ` `  `// Query type 1: update string position i with ` `// character x. ` `void` `qType1(``int` `l, ``int` `x, ``char` `str[]) ` `{ ` `    ``str[l - 1] = x; ` `} ` ` `  `// Print "Yes" if range [L..R] can form palindrome, ` `// else print "No". ` `void` `qType2(``int` `l, ``int` `r, ``char` `str[]) ` `{ ` `    ``int` `freq[27] = { 0 }; ` ` `  `    ``// Find the frequency of each character in ` `    ``// S[L...R]. ` `    ``for` `(``int` `i = l - 1; i <= r - 1; i++) ` `        ``freq[str[i] - ``'a'``]++; ` ` `  `    ``// Checking if more than one character have ` `    ``// frequency greater than 1. ` `    ``int` `count = 0; ` `    ``for` `(``int` `j = 0; j < 26; j++) ` `        ``if` `(freq[j] % 2) ` `            ``count++; ` ` `  `    ``(count <= 1) ? (cout << ``"Yes"` `<< endl) : (cout << ``"No"` `<< endl); ` `} ` ` `  `// Driven Program ` `int` `main() ` `{ ` `    ``char` `str[] = ``"geeksforgeeks"``; ` `    ``int` `n = ``strlen``(str); ` ` `  `    ``qType1(4, ``'g'``, str); ` `    ``qType2(1, 4, str); ` `    ``qType2(2, 3, str); ` `    ``qType1(10, ``'t'``, str); ` `    ``qType2(10, 11, str); ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java program to Queries on substring ` `// palindrome formation. ` ` `  `class` `GFG { ` ` `  `    ``// Query type 1: update string ` `    ``// position i with character x. ` `    ``static` `void` `qType1(``int` `l, ``int` `x, ``char` `str[]) ` `    ``{ ` `        ``str[l - ``1``] = (``char``)x; ` `    ``} ` ` `  `    ``// Print "Yes" if range [L..R] can form ` `    ``// palindrome, else print "No". ` `    ``static` `void` `qType2(``int` `l, ``int` `r, ``char` `str[]) ` `    ``{ ` `        ``int` `freq[] = ``new` `int``[``27``]; ` ` `  `        ``// Find the frequency of each ` `        ``// character in S[L...R]. ` `        ``for` `(``int` `i = l - ``1``; i <= r - ``1``; i++) { ` `            ``freq[str[i] - ``'a'``]++; ` `        ``} ` ` `  `        ``// Checking if more than one character ` `        ``// have frequency greater than 1. ` `        ``int` `count = ``0``; ` `        ``for` `(``int` `j = ``0``; j < ``26``; j++) { ` `            ``if` `(freq[j] % ``2` `!= ``0``) { ` `                ``count++; ` `            ``} ` `        ``} ` `        ``if` `(count <= ``1``) { ` `            ``System.out.println(``"Yes"``); ` `        ``} ` `        ``else` `{ ` `            ``System.out.println(``"No"``); ` `        ``} ` `    ``} ` ` `  `    ``// Driven code ` `    ``public` `static` `void` `main(String[] args) ` `    ``{ ` `        ``char` `str[] = ``"geeksforgeeks"``.toCharArray(); ` `        ``int` `n = str.length; ` ` `  `        ``qType1(``4``, ``'g'``, str); ` `        ``qType2(``1``, ``4``, str); ` `        ``qType2(``2``, ``3``, str); ` `        ``qType1(``10``, ``'t'``, str); ` `        ``qType2(``10``, ``11``, str); ` `    ``} ` `} ` ` `  `// This code is contributed by 29AjayKumar `

## Python3

 `# Python3 program to Queries on substring  ` `# palindrome formation. ` ` `  `# Query type 1: update string position  ` `# i with character x. ` `def` `qType1(l, x, str1): ` `    ``str1[l ``-` `1``] ``=` `x ` ` `  `# Print"Yes" if range [L..R] can form palindrome, ` `# else print"No". ` `def` `qType2(l, r, str1): ` ` `  `    ``freq ``=` `[``0` `for` `i ``in` `range``(``27``)]  ` ` `  `    ``# Find the frequency of  ` `    ``# each character in S[L...R]. ` `    ``for` `i ``in` `range``(l ``-` `1``, r): ` `        ``freq[``ord``(str1[i]) ``-` `ord``(``'a'``)] ``+``=` `1` ` `  `    ``# Checking if more than one character  ` `    ``# have frequency greater than 1. ` `    ``count ``=` `0` `    ``for` `j ``in` `range``(``26``): ` `        ``if` `(freq[j] ``%` `2``): ` `            ``count ``+``=` `1` `    ``if` `count <``=` `1``: ` `        ``print``(``"Yes"``) ` `    ``else``: ` `        ``print``(``"No"``) ` ` `  `# Driver Code ` `str1 ``=` `"geeksforgeeks"` `str2 ``=` `[i ``for` `i ``in` `str1] ` `n ``=` `len``(str2) ` ` `  `qType1(``4``, ``'g'``, str2) ` `qType2(``1``, ``4``, str2) ` `qType2(``2``, ``3``, str2) ` `qType1(``10``, ``'t'``, str2) ` `qType2(``10``, ``11``, str2) ` ` `  `# This code is contributed by mohit kumar `

## C#

 `// C# program to Queries on substring ` `// palindrome formation. ` `using` `System; ` ` `  `class` `GFG { ` ` `  `    ``// Query type 1: update string ` `    ``// position i with character x. ` `    ``static` `void` `qType1(``int` `l, ``int` `x, ``char``[] str) ` `    ``{ ` `        ``str[l - 1] = (``char``)x; ` `    ``} ` ` `  `    ``// Print "Yes" if range [L..R] can form ` `    ``// palindrome, else print "No". ` `    ``static` `void` `qType2(``int` `l, ``int` `r, ``char``[] str) ` `    ``{ ` `        ``int``[] freq = ``new` `int``[27]; ` ` `  `        ``// Find the frequency of each ` `        ``// character in S[L...R]. ` `        ``for` `(``int` `i = l - 1; i <= r - 1; i++) { ` `            ``freq[str[i] - ``'a'``]++; ` `        ``} ` ` `  `        ``// Checking if more than one character ` `        ``// have frequency greater than 1. ` `        ``int` `count = 0; ` `        ``for` `(``int` `j = 0; j < 26; j++) { ` `            ``if` `(freq[j] % 2 != 0) { ` `                ``count++; ` `            ``} ` `        ``} ` `        ``if` `(count <= 1) { ` `            ``Console.WriteLine(``"Yes"``); ` `        ``} ` `        ``else` `{ ` `            ``Console.WriteLine(``"No"``); ` `        ``} ` `    ``} ` ` `  `    ``// Driver code ` `    ``public` `static` `void` `Main(String[] args) ` `    ``{ ` `        ``char``[] str = ``"geeksforgeeks"``.ToCharArray(); ` `        ``int` `n = str.Length; ` ` `  `        ``qType1(4, ``'g'``, str); ` `        ``qType2(1, 4, str); ` `        ``qType2(2, 3, str); ` `        ``qType1(10, ``'t'``, str); ` `        ``qType2(10, 11, str); ` `    ``} ` `} ` ` `  `// This code contributed by Rajput-Ji `

## PHP

 ` `

## Javascript

 ` `

Output

```Yes
Yes
No
```

Time Complexity: O(R-L), because qType1 function updates a single character in the string which takes O(1) time and qType2 function finds the frequency of each character in a given range of the string which takes O(R-L) time where R and L are the ending and starting indices of the range. It then checks if more than one character has a frequency greater than 1. Since the size of the frequency array is constant (26), this operation takes O(1) time. Therefore, the time complexity is O(R-L).
Space Complexity: O(1)

Method 2 : Use Binary Indexed Tree
The efficient approach can be maintain 26 Binary Index Tree for each alphabet.
Define a function getFrequency(i, u) which returns the frequency of ‘u’ in the ith prefix. Frequency of character ‘u’ in range L…R can be find by getFrequency(R, u) – getFrequency(L-1, u).
Whenever update(Query 1) comes to change S[i] from character ‘u’ to ‘v’. BIT[u] is updated with -1 at index i and BIT[v] is updated with +1 at index i.

Below is the implementation of this approach:

## C++

 `// C++ program to Queries on substring palindrome ` `// formation. ` `#include ` `#define max 1000 ` `using` `namespace` `std; ` ` `  `// Return the frequency of the character in the ` `// i-th prefix. ` `int` `getFrequency(``int` `tree[max][27], ``int` `idx, ``int` `i) ` `{ ` `    ``int` `sum = 0; ` ` `  `    ``while` `(idx > 0) { ` `        ``sum += tree[idx][i]; ` `        ``idx -= (idx & -idx); ` `    ``} ` ` `  `    ``return` `sum; ` `} ` ` `  `// Updating the BIT ` `void` `update(``int` `tree[max][27], ``int` `idx, ``int` `val, ``int` `i) ` `{ ` `    ``while` `(idx <= max) { ` `        ``tree[idx][i] += val; ` `        ``idx += (idx & -idx); ` `    ``} ` `} ` ` `  `// Query to update the character in the string. ` `void` `qType1(``int` `tree[max][27], ``int` `l, ``int` `x, ``char` `str[]) ` `{ ` `    ``// Adding -1 at L position ` `    ``update(tree, l, -1, str[l - 1] - 97 + 1); ` ` `  `    ``// Updating the character ` `    ``str[l - 1] = x; ` ` `  `    ``// Adding +1 at R position ` `    ``update(tree, l, 1, str[l - 1] - 97 + 1); ` `} ` ` `  `// Query to find if rearrangement of character in range ` `// L...R can form palindrome ` `void` `qType2(``int` `tree[max][27], ``int` `l, ``int` `r, ``char` `str[]) ` `{ ` `    ``int` `count = 0; ` ` `  `    ``for` `(``int` `i = 1; i <= 26; i++) { ` `        ``// Checking on the first character of the string S. ` `        ``if` `(l == 1) { ` `            ``if` `(getFrequency(tree, r, i) % 2 == 1) ` `                ``count++; ` `        ``} ` `        ``else` `{ ` `            ``// Checking if frequency of character is even or odd. ` `            ``if` `((getFrequency(tree, r, i) - getFrequency(tree, l - 1, i)) % 2 == 1) ` `                ``count++; ` `        ``} ` `    ``} ` ` `  `    ``(count <= 1) ? (cout << ``"Yes"` `<< endl) : (cout << ``"No"` `<< endl); ` `} ` ` `  `// Creating the Binary Index Tree of all alphabet ` `void` `buildBIT(``int` `tree[max][27], ``char` `str[], ``int` `n) ` `{ ` `    ``memset``(tree, 0, ``sizeof``(tree)); ` ` `  `    ``for` `(``int` `i = 0; i < n; i++) ` `        ``update(tree, i + 1, 1, str[i] - 97 + 1); ` `} ` ` `  `// Driven Program ` `int` `main() ` `{ ` `    ``char` `str[] = ``"geeksforgeeks"``; ` `    ``int` `n = ``strlen``(str); ` ` `  `    ``int` `tree[max][27]; ` `    ``buildBIT(tree, str, n); ` ` `  `    ``qType1(tree, 4, ``'g'``, str); ` `    ``qType2(tree, 1, 4, str); ` `    ``qType2(tree, 2, 3, str); ` `    ``qType1(tree, 10, ``'t'``, str); ` `    ``qType2(tree, 10, 11, str); ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java program to Queries on substring palindrome ` `// formation. ` ` `  `import` `java.util.*; ` ` `  `class` `GFG { ` ` `  `    ``static` `int` `max = ``1000``; ` ` `  `    ``// Return the frequency of the character in the ` `    ``// i-th prefix. ` `    ``static` `int` `getFrequency(``int` `tree[][], ``int` `idx, ``int` `i) ` `    ``{ ` `        ``int` `sum = ``0``; ` ` `  `        ``while` `(idx > ``0``) { ` `            ``sum += tree[idx][i]; ` `            ``idx -= (idx & -idx); ` `        ``} ` ` `  `        ``return` `sum; ` `    ``} ` ` `  `    ``// Updating the BIT ` `    ``static` `void` `update(``int` `tree[][], ``int` `idx, ` `                       ``int` `val, ``int` `i) ` `    ``{ ` `        ``while` `(idx <= max) { ` `            ``tree[idx][i] += val; ` `            ``idx += (idx & -idx); ` `        ``} ` `    ``} ` ` `  `    ``// Query to update the character in the string. ` `    ``static` `void` `qType1(``int` `tree[][], ``int` `l, ``int` `x, ``char` `str[]) ` `    ``{ ` `        ``// Adding -1 at L position ` `        ``update(tree, l, -``1``, str[l - ``1``] - ``97` `+ ``1``); ` ` `  `        ``// Updating the character ` `        ``str[l - ``1``] = (``char``)x; ` ` `  `        ``// Adding +1 at R position ` `        ``update(tree, l, ``1``, str[l - ``1``] - ``97` `+ ``1``); ` `    ``} ` ` `  `    ``// Query to find if rearrangement of character in range ` `    ``// L...R can form palindrome ` `    ``static` `void` `qType2(``int` `tree[][], ``int` `l, ``int` `r, ``char` `str[]) ` `    ``{ ` `        ``int` `count = ``0``; ` ` `  `        ``for` `(``int` `i = ``1``; i <= ``26``; i++) { ` `            ``// Checking on the first character of the string S. ` `            ``if` `(l == ``1``) { ` `                ``if` `(getFrequency(tree, r, i) % ``2` `== ``1``) ` `                    ``count++; ` `            ``} ` `            ``else` `{ ` `                ``// Checking if frequency of character is even or odd. ` `                ``if` `((getFrequency(tree, r, i) - getFrequency(tree, l - ``1``, i)) % ``2` `== ``1``) ` `                    ``count++; ` `            ``} ` `        ``} ` ` `  `        ``if` `(count <= ``1``) ` `            ``System.out.println(``"Yes"``); ` `        ``else` `            ``System.out.println(``"No"``); ` `    ``} ` ` `  `    ``// Creating the Binary Index Tree of all alphabet ` `    ``static` `void` `buildBIT(``int` `tree[][], ``char` `str[], ``int` `n) ` `    ``{ ` ` `  `        ``for` `(``int` `i = ``0``; i < n; i++) ` `            ``update(tree, i + ``1``, ``1``, str[i] - ``97` `+ ``1``); ` `    ``} ` ` `  `    ``// Driver code ` `    ``public` `static` `void` `main(String[] args) ` `    ``{ ` `        ``char` `str[] = ``"geeksforgeeks"``.toCharArray(); ` `        ``int` `n = str.length; ` ` `  `        ``int` `tree[][] = ``new` `int``[max][``27``]; ` `        ``buildBIT(tree, str, n); ` ` `  `        ``qType1(tree, ``4``, ``'g'``, str); ` `        ``qType2(tree, ``1``, ``4``, str); ` `        ``qType2(tree, ``2``, ``3``, str); ` `        ``qType1(tree, ``10``, ``'t'``, str); ` `        ``qType2(tree, ``10``, ``11``, str); ` `    ``} ` `} ` ` `  `/* This code contributed by PrinciRaj1992 */`

## Python3

 `# Python3 program to Queries on substring palindrome ` `# formation. ` ` `  `max` `=` `1000``; ` ` `  `# Return the frequency of the character in the ` `# i-th prefix. ` `def` `getFrequency(tree, idx, i): ` `    ``sum` `=` `0``; ` ` `  `    ``while` `(idx > ``0``): ` `        ``sum` `+``=` `tree[idx][i]; ` `        ``idx ``-``=` `(idx & ``-``idx); ` ` `  `    ``return` `sum``; ` ` `  `# Updating the BIT ` `def` `update(tree, idx, val, i): ` `    ``while` `(idx <``=` `max``): ` `        ``tree[idx][i] ``+``=` `val; ` `        ``idx ``+``=` `(idx & ``-``idx); ` ` `  `# Query to update the character in the string. ` `def` `qType1(tree, l, x, str1): ` ` `  `    ``# Adding -1 at L position ` `    ``update(tree, l, ``-``1``, ``ord``(str1[l ``-` `1``]) ``-` `97` `+` `1``); ` ` `  `    ``# Updating the character ` `    ``list1 ``=` `list``(str1) ` `    ``list1[l ``-` `1``] ``=` `x; ` `    ``str1 ``=` `''.join(list1); ` ` `  `    ``# Adding +1 at R position ` `    ``update(tree, l, ``1``, ``ord``(str1[l ``-` `1``]) ``-` `97` `+` `1``); ` ` `  `# Query to find if rearrangement of character in range ` `# L...R can form palindrome ` `def` `qType2(tree, l, r, str1): ` `    ``count ``=` `0``; ` ` `  `    ``for` `i ``in` `range``(``1``, ``27``): ` `         `  `        ``# Checking on the first character of the string S. ` `        ``if` `(l ``=``=` `1``): ` `            ``if` `(getFrequency(tree, r, i) ``%` `2` `=``=` `1``): ` `                ``count``+``=``1``; ` `        ``else``: ` `            ``# Checking if frequency of character is even or odd. ` `            ``if` `((getFrequency(tree, r, i) ``-`  `                ``getFrequency(tree, l ``-` `1``, i)) ``%` `2` `=``=` `1``): ` `                ``count ``+``=` `1``; ` ` `  `    ``print``(``"Yes"``) ``if``(count <``=` `1``) ``else` `print``(``"No"``); ` ` `  `# Creating the Binary Index Tree of all alphabet ` `def` `buildBIT(tree,str1, n): ` ` `  `    ``for` `i ``in` `range``(n): ` `        ``update(tree, i ``+` `1``, ``1``, ``ord``(str1[i]) ``-` `97` `+` `1``); ` ` `  `# Driver code ` ` `  `str1 ``=` `"geeksforgeeks"``; ` `n ``=` `len``(str1); ` ` `  `tree ``=` `[[``0` `for` `x ``in` `range``(``27``)] ``for` `y ``in` `range``(``max``)]; ` `buildBIT(tree, str1, n); ` ` `  `qType1(tree, ``4``, ``'g'``, str1); ` `qType2(tree, ``1``, ``4``, str1); ` `qType2(tree, ``2``, ``3``, str1); ` `qType1(tree, ``10``, ``'t'``, str1); ` `qType2(tree, ``10``, ``11``, str1); ` ` `  ` `  `# This code is contributed by mits `

## C#

 `// C# program to Queries on substring palindrome ` `// formation. ` `using` `System; ` ` `  `class` `GFG ` `{ ` ` `  `    ``static` `int` `max = 1000; ` ` `  `    ``// Return the frequency of the character in the ` `    ``// i-th prefix. ` `    ``static` `int` `getFrequency(``int` `[,]tree, ``int` `idx, ``int` `i) ` `    ``{ ` `        ``int` `sum = 0; ` ` `  `        ``while` `(idx > 0) ` `        ``{ ` `            ``sum += tree[idx,i]; ` `            ``idx -= (idx & -idx); ` `        ``} ` ` `  `        ``return` `sum; ` `    ``} ` ` `  `    ``// Updating the BIT ` `    ``static` `void` `update(``int` `[,]tree, ``int` `idx, ` `                    ``int` `val, ``int` `i) ` `    ``{ ` `        ``while` `(idx <= max)  ` `        ``{ ` `            ``tree[idx,i] += val; ` `            ``idx += (idx & -idx); ` `        ``} ` `    ``} ` ` `  `    ``// Query to update the character in the string. ` `    ``static` `void` `qType1(``int` `[,]tree, ``int` `l, ``int` `x, ``char` `[]str) ` `    ``{ ` `        ``// Adding -1 at L position ` `        ``update(tree, l, -1, str[l - 1] - 97 + 1); ` ` `  `        ``// Updating the character ` `        ``str[l - 1] = (``char``)x; ` ` `  `        ``// Adding +1 at R position ` `        ``update(tree, l, 1, str[l - 1] - 97 + 1); ` `    ``} ` ` `  `    ``// Query to find if rearrangement of character in range ` `    ``// L...R can form palindrome ` `    ``static` `void` `qType2(``int` `[,]tree, ``int` `l, ``int` `r, ``char` `[]str) ` `    ``{ ` `        ``int` `count = 0; ` ` `  `        ``for` `(``int` `i = 1; i <= 26; i++)  ` `        ``{ ` `            ``// Checking on the first character of the string S. ` `            ``if` `(l == 1)  ` `            ``{ ` `                ``if` `(getFrequency(tree, r, i) % 2 == 1) ` `                    ``count++; ` `            ``} ` `            ``else` `            ``{ ` `                ``// Checking if frequency of character is even or odd. ` `                ``if` `((getFrequency(tree, r, i) - getFrequency(tree, l - 1, i)) % 2 == 1) ` `                    ``count++; ` `            ``} ` `        ``} ` ` `  `        ``if` `(count <= 1) ` `            ``Console.WriteLine(``"Yes"``); ` `        ``else` `            ``Console.WriteLine(``"No"``); ` `    ``} ` ` `  `    ``// Creating the Binary Index Tree of all alphabet ` `    ``static` `void` `buildBIT(``int` `[,]tree, ``char` `[]str, ``int` `n) ` `    ``{ ` ` `  `        ``for` `(``int` `i = 0; i < n; i++) ` `            ``update(tree, i + 1, 1, str[i] - 97 + 1); ` `    ``} ` ` `  `    ``// Driver code ` `    ``static` `void` `Main() ` `    ``{ ` `        ``char` `[]str = ``"geeksforgeeks"``.ToCharArray(); ` `        ``int` `n = str.Length; ` ` `  `        ``int``[,] tree = ``new` `int``[max,27]; ` `        ``buildBIT(tree, str, n); ` ` `  `        ``qType1(tree, 4, ``'g'``, str); ` `        ``qType2(tree, 1, 4, str); ` `        ``qType2(tree, 2, 3, str); ` `        ``qType1(tree, 10, ``'t'``, str); ` `        ``qType2(tree, 10, 11, str); ` `    ``} ` `} ` ` `  `// This code contributed by mits  `

## Javascript

 ` `

Output:

```Yes
Yes
No```

Time Complexity:- O(q * log n), there are q queries and every query takes O(log n) time.
Space Complexity:- O(n * 26)

Previous
Next