public
class
GFG {
static
int
p =
101
;
static
int
MOD =
1000000007
;
static
class
Query {
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.charAt(L++) != str.charAt(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.charAt(
0
);
for
(
int
i =
2
; i <= n; i++) {
prefix[i] = (prefix[i -
1
] % MOD
+ (str.charAt(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.charAt(n -
1
);
for
(
int
i = n -
2
, j =
2
; i >=
0
&& j <= n; i--, j++) {
suffix[j] = (suffix[j -
1
] % MOD
+ (str.charAt(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
) {
System.out.printf(
"The Substring [%d %d] is a "
+
"palindrome\n"
,
L, R);
}
else
{
System.out.printf(
"The Substring [%d %d] is not a "
+
"palindrome\n"
,
L, R);
}
}
else
{
System.out.printf(
"The Substring [%d %d] is not a "
+
"palindrome\n"
,
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);
}
}