Palindrome Substring Queries | A C # program to answer queries to check whether the substrings are palindrome or not efficiently ; Structure to represent a query . A query consists of ( L , R ) and we have to answer whether the substring from index - L to R is a palindrome or not ; A function to check if a string str is palindrome in the ranfe L to R ; Keep comparing characters while they are same ; A Function to find pow ( base , exponent ) % MOD in log ( exponent ) time ; A Function to calculate Modulo Multiplicative Inverse of ' n ' ; A Function to calculate the prefix hash ; A Function to calculate the suffix hash Suffix hash is nothing but the prefix hash of the reversed string ; A Function to answer the Queries ; Hash Value of Substring [ L , R ] ; Reverse Hash Value of Substring [ L , R ] ; If both are equal then the substring is a palindrome ; A Dynamic Programming Based Approach to compute the powers of 101 ; 101 ^ 0 = 1 ; Driver code ; A Table to store the powers of 101 ; Arrays to hold prefix and suffix hash values ; Compute Prefix Hash and Suffix Hash Arrays
using System ; class GFG { static int p = 101 ; static int MOD = 1000000007 ; public class Query { public int L , R ; public Query ( int L , int R ) { this . L = L ; this . R = R ; } } ; static Boolean isPalindrome ( String str , int L , int R ) { while ( R > L ) { if ( str [ L ++ ] != str [ R -- ] ) { return ( false ) ; } } return ( true ) ; } static int modPow ( int Base , int exponent ) { if ( exponent == 0 ) { return 1 ; } if ( exponent == 1 ) { return Base ; } int temp = modPow ( Base , exponent / 2 ) ; if ( exponent % 2 == 0 ) { return ( temp % MOD * temp % MOD ) % MOD ; } else { return ( ( ( temp % MOD * temp % MOD ) % MOD ) * Base % MOD ) % MOD ; } } static int findMMI ( int n ) { return modPow ( n , MOD - 2 ) ; } static void computePrefixHash ( String str , int n , int [ ] prefix , int [ ] power ) { prefix [ 0 ] = 0 ; prefix [ 1 ] = str [ 0 ] ; for ( int i = 2 ; i <= n ; i ++ ) { prefix [ i ] = ( prefix [ i - 1 ] % MOD + ( str [ i - 1 ] % MOD * power [ i - 1 ] % MOD ) % MOD ) % MOD ; } return ; } static void computeSuffixHash ( String str , int n , int [ ] suffix , int [ ] power ) { suffix [ 0 ] = 0 ; suffix [ 1 ] = str [ n - 1 ] ; for ( int i = n - 2 , j = 2 ; i >= 0 && j <= n ; i -- , j ++ ) { suffix [ j ] = ( suffix [ j - 1 ] % MOD + ( str [ i ] % MOD * power [ j - 1 ] % MOD ) % MOD ) % MOD ; } return ; } static void queryResults ( String str , Query [ ] q , int m , int n , int [ ] prefix , int [ ] suffix , int [ ] power ) { for ( int i = 0 ; i <= m - 1 ; i ++ ) { int L = q [ i ] . L ; int R = q [ i ] . R ; long hash_LR = ( ( prefix [ R + 1 ] - prefix [ L ] + MOD ) % MOD * findMMI ( power [ L ] ) % MOD ) % MOD ; long reverse_hash_LR = ( ( suffix [ n - L ] - suffix [ n - R - 1 ] + MOD ) % MOD * findMMI ( power [ n - R - 1 ] ) % MOD ) % MOD ; if ( hash_LR == reverse_hash_LR ) { if ( isPalindrome ( str , L , R ) == true ) { Console . Write ( " The ▁ Substring ▁ [ { 0 } ▁ { 1 } ] ▁ is ▁ a ▁ " + " palindrome STRNEWLINE " , L , R ) ; } else { Console . Write ( " The ▁ Substring ▁ [ { 0 } ▁ { 1 } ] ▁ is ▁ not ▁ a ▁ " + " palindrome STRNEWLINE " , L , R ) ; } } else { Console . Write ( " The ▁ Substring ▁ [ { 0 } ▁ { 1 } ] ▁ is ▁ not ▁ a ▁ " + " palindrome STRNEWLINE " , L , R ) ; } } return ; } static void computePowers ( int [ ] power , int n ) { power [ 0 ] = 1 ; for ( int i = 1 ; i <= n ; i ++ ) { power [ i ] = ( power [ i - 1 ] % MOD * p % MOD ) % MOD ; } return ; } public static void Main ( String [ ] args ) { String str = " abaaabaaaba " ; int n = str . Length ; int [ ] power = new int [ n + 1 ] ; computePowers ( power , n ) ; int [ ] prefix = new int [ n + 1 ] ; int [ ] suffix = new int [ n + 1 ] ; computePrefixHash ( str , n , prefix , power ) ; computeSuffixHash ( str , n , suffix , power ) ; Query [ ] q = { new Query ( 0 , 10 ) , new Query ( 5 , 8 ) , new Query ( 2 , 5 ) , new Query ( 5 , 9 ) } ; int m = q . Length ; queryResults ( str , q , m , n , prefix , suffix , power ) ; } }