/**
*
* @author chang
* created on 20/02/15
*/
import java.util.* ;
import java.io.* ;
class FindPalindrome {
public static void main
( String [ ] args
) { FindPalindromeSolver ob = new FindPalindromeSolver( ) ;
ob.solve ( ) ;
}
}
class Manacher{
int [ ] odd,even;
int [ ] [ ] rmqEven, rmqOdd;
int n;
Manacher( int size) {
n = size;
even = new int [ n] ;
odd = new int [ n] ;
rmqEven = new int [ 20 ] [ n] ;
rmqOdd = new int [ 20 ] [ n] ;
}
/**
* builds for odd and even length
* for odd actual length of palindrome at center i is odd[i]+1
*/
int st = 0 ,en = - 1 ;
for ( int i = 0 ; i < n; ++ i) {
int dR = en- i, size = 1 ;
if ( en >= i)
size
+= Math .
min ( dR,odd
[ st
+ dR
] ) ; while ( i- size >= 0 && i+ size < n && msg.charAt ( i+ size) == msg.charAt ( i- size) )
++ size;
size -= 1 ;
odd[ i] = size;
if ( i+ size > en) {
en = i + size;
st = i - size;
}
}
st = 0 ;
en = - 1 ;
for ( int i = 0 ; i < n; ++ i) {
int dR = en- i, size = 1 ;
if ( en >= i)
size
+= Math .
min ( dR
+ 1 ,even
[ st
+ dR
+ 1 ] ) ; while ( i- size >= 0 && i+ size- 1 < n && msg.charAt ( i+ size- 1 ) == msg.charAt ( i- size) )
++ size;
size -= 1 ;
even[ i] = size;
if ( i+ size- 1 > en) {
en = i+ size- 1 ;
st = i- size;
}
}
}
/**
* build the min rmq for starting point of palindrome
* centered at i
*/
void buildRMQ( ) {
for ( int i = 0 ; i < n; ++ i) {
rmqOdd[ 0 ] [ i] = i- odd[ i] ;
rmqEven[ 0 ] [ i] = i- even[ i] ;
}
for ( int h = 1 , step = 1 ; ( 1 << h) < n; ++ h, step <<= 1 ) {
for ( int i = 0 ; i < n; ++ i) {
if ( ( i+ ( 1 << h) ) >= n)
continue ;
rmqOdd
[ h
] [ i
] = Math .
min ( rmqOdd
[ h
- 1 ] [ i
] ,rmqOdd
[ h
- 1 ] [ i
+ step
] ) ; rmqEven
[ h
] [ i
] = Math .
min ( rmqEven
[ h
- 1 ] [ i
] ,rmqEven
[ h
- 1 ] [ i
+ step
] ) ; }
}
}
int getOdd( int x,int y) {
int d = 0 , stp = 1 ;
while ( x+ stp- 1 <= y) {
stp <<= 1 ;
++ d;
}
d -= 1 ;
stp >>= 1 ;
return Math .
min ( rmqOdd
[ d
] [ x
] , rmqOdd
[ d
] [ y
- stp
+ 1 ] ) ; }
int getEven( int x,int y) {
int d = 0 , stp = 1 ;
while ( x+ stp- 1 <= y) {
stp <<= 1 ;
++ d;
}
d -= 1 ;
stp >>= 1 ;
return Math .
min ( rmqEven
[ d
] [ x
] , rmqEven
[ d
] [ y
- stp
+ 1 ] ) ; }
} ;
class FindPalindromeSolver {
int [ ] allowed;
int [ ] length;
public void solve( ) {
MyScanner in = new MyScanner( ) ;
msg = in.next ( ) ;
int n = msg.length ( ) ;
allowed = new int [ n] ;
length = new int [ n] ;
for ( int i = 0 ; i < n; ++ i) {
allowed[ i] = in.nextInt ( ) ;
length[ i] = 0 ;
}
Manacher manacher = new Manacher( n) ;
manacher.build ( msg) ;
manacher.buildRMQ ( ) ;
for ( int i = 0 ; i < n; ++ i) {
int endOdd = i + ( allowed[ i] - 1 ) / 2 ;
int endEven = i + allowed[ i] / 2 ;
int st = i, en = endOdd;
int ans = - 1 ;
while ( st <= en) {
int mid = ( st+ en) / 2 ;
int response = manacher.getOdd ( mid,endOdd) ;
if ( response <= i) {
ans = mid;
st = mid+ 1 ;
} else
en = mid- 1 ;
}
if ( ans != - 1 )
length
[ i
] = Math .
max ( length
[ i
] ,
( ans
- i
) * 2 + 1 ) ;
st = i; en = endEven;
ans = - 1 ;
while ( st <= en) {
int mid = ( st+ en) / 2 ;
int response = manacher.getEven ( mid,endEven) ;
if ( response <= i) {
ans = mid;
st = mid+ 1 ;
} else
en = mid- 1 ;
}
if ( ans != - 1 )
length
[ i
] = Math .
max ( length
[ i
] ,
( ans
- i
) * 2 ) ; }
for ( int i = 0 ; i < n; ++ i)
out.print ( length[ i] + " " ) ;
out.println ( ) ;
out.close ( ) ;
}
//-----------PrintWriter for faster output-------------
//-----------MyScanner class for faster input----------
public static class MyScanner {
public MyScanner( ) {
}
while ( st == null || ! st.hasMoreElements ( ) ) {
try {
e.printStackTrace ( ) ;
}
}
return st.nextToken ( ) ;
}
int nextInt( ) {
}
long nextLong( ) {
return Long .
parseLong ( next
( ) ) ; }
double nextDouble( ) {
return Double .
parseDouble ( next
( ) ) ; }
try {
str = br.readLine ( ) ;
e.printStackTrace ( ) ;
}
return str;
}
}
}
LyoqCiAqIAogKiBAYXV0aG9yIGNoYW5nCiAqIGNyZWF0ZWQgb24gMjAvMDIvMTUKICovCiAKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5pby4qOwogCmNsYXNzIEZpbmRQYWxpbmRyb21lIHsKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICBGaW5kUGFsaW5kcm9tZVNvbHZlciBvYiA9IG5ldyBGaW5kUGFsaW5kcm9tZVNvbHZlcigpOwogICAgICAgIG9iLnNvbHZlKCk7CiAgICB9Cn0KIApjbGFzcyBNYW5hY2hlcnsKICAgIGludFtdIG9kZCxldmVuOwogICAgaW50W11bXSBybXFFdmVuLCBybXFPZGQ7CiAgICBpbnQgbjsKIAogICAgTWFuYWNoZXIoaW50IHNpemUpewogICAgICAgIG4gPSBzaXplOwogICAgICAgIGV2ZW4gPSBuZXcgaW50W25dOwogICAgICAgIG9kZCA9IG5ldyBpbnRbbl07CiAgICAgICAgcm1xRXZlbiA9IG5ldyBpbnRbMjBdW25dOwogICAgICAgIHJtcU9kZCA9IG5ldyBpbnRbMjBdW25dOwogICAgfQogCiAgICAvKioKICAgICAqIGJ1aWxkcyBmb3Igb2RkIGFuZCBldmVuIGxlbmd0aAogICAgICogZm9yIG9kZCBhY3R1YWwgbGVuZ3RoIG9mIHBhbGluZHJvbWUgYXQgY2VudGVyIGkgaXMgb2RkW2ldKzEKICAgICAqLwogICAgdm9pZCBidWlsZChTdHJpbmcgbXNnKXsKICAgICAgICBpbnQgc3QgPSAwLGVuID0gLTE7CiAKICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbjsgKytpKXsKICAgICAgICAgICAgaW50IGRSID0gZW4taSwgc2l6ZSA9IDE7CiAgICAgICAgICAgIGlmIChlbiA+PSBpKQogICAgICAgICAgICAgICAgc2l6ZSArPSBNYXRoLm1pbihkUixvZGRbc3QrZFJdKTsKICAgICAgICAgICAgd2hpbGUoaS1zaXplID49IDAgJiYgaStzaXplIDwgbiAmJiBtc2cuY2hhckF0KGkrc2l6ZSkgPT0gbXNnLmNoYXJBdChpLXNpemUpKQogICAgICAgICAgICAgICAgKytzaXplOwogICAgICAgICAgICBzaXplIC09IDE7CiAgICAgICAgICAgIG9kZFtpXSA9IHNpemU7CiAgICAgICAgICAgIGlmIChpK3NpemUgPiBlbikgewogICAgICAgICAgICAgICAgZW4gPSBpICsgc2l6ZTsKICAgICAgICAgICAgICAgIHN0ID0gaSAtIHNpemU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAKICAgICAgICBzdCA9IDA7CiAgICAgICAgZW4gPSAtMTsKICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbjsgKytpKXsKICAgICAgICAgICAgaW50IGRSID0gZW4taSwgc2l6ZSA9IDE7CiAgICAgICAgICAgIGlmIChlbiA+PSBpKQogICAgICAgICAgICAgICAgc2l6ZSArPSBNYXRoLm1pbihkUisxLGV2ZW5bc3QrZFIrMV0pOwogICAgICAgICAgICB3aGlsZShpLXNpemUgPj0gMCAmJiBpK3NpemUtMSA8IG4gJiYgbXNnLmNoYXJBdChpK3NpemUtMSkgPT0gbXNnLmNoYXJBdChpLXNpemUpKQogICAgICAgICAgICAgICAgKytzaXplOwogICAgICAgICAgICBzaXplIC09IDE7CiAgICAgICAgICAgIGV2ZW5baV0gPSBzaXplOwogICAgICAgICAgICBpZiAoaStzaXplLTEgPiBlbil7CiAgICAgICAgICAgICAgICBlbiA9IGkrc2l6ZS0xOwogICAgICAgICAgICAgICAgc3QgPSBpLXNpemU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAKICAgIC8qKgogICAgICogYnVpbGQgdGhlIG1pbiBybXEgZm9yIHN0YXJ0aW5nIHBvaW50IG9mIHBhbGluZHJvbWUKICAgICAqIGNlbnRlcmVkIGF0IGkKICAgICAqLwogICAgdm9pZCBidWlsZFJNUSgpewogICAgICAgIGZvcihpbnQgaSA9IDA7IGkgPCBuOyArK2kpewogICAgICAgICAgICBybXFPZGRbMF1baV0gPSBpLW9kZFtpXTsKICAgICAgICAgICAgcm1xRXZlblswXVtpXSA9IGktZXZlbltpXTsKICAgICAgICB9CiAKICAgICAgICBmb3IoaW50IGggPSAxLCBzdGVwID0gMTsgKDEgPDwgaCkgPCBuOyArK2gsIHN0ZXAgPDw9IDEpewogICAgICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbjsgKytpKXsKICAgICAgICAgICAgICAgIGlmICgoaSsoMSA8PCBoKSkgPj0gbikKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIHJtcU9kZFtoXVtpXSA9IE1hdGgubWluKHJtcU9kZFtoLTFdW2ldLHJtcU9kZFtoLTFdW2krc3RlcF0pOwogICAgICAgICAgICAgICAgcm1xRXZlbltoXVtpXSA9IE1hdGgubWluKHJtcUV2ZW5baC0xXVtpXSxybXFFdmVuW2gtMV1baStzdGVwXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAKICAgIGludCBnZXRPZGQoaW50IHgsaW50IHkpewogICAgICAgIGludCBkID0gMCwgc3RwID0gMTsKICAgICAgICB3aGlsZSh4K3N0cC0xIDw9IHkpewogICAgICAgICAgICBzdHAgPDw9IDE7CiAgICAgICAgICAgICsrZDsKICAgICAgICB9CiAKICAgICAgICBkIC09IDE7CiAgICAgICAgc3RwID4+PSAxOwogICAgICAgIHJldHVybiBNYXRoLm1pbihybXFPZGRbZF1beF0sIHJtcU9kZFtkXVt5LXN0cCsxXSk7CiAgICB9CiAKICAgIGludCBnZXRFdmVuKGludCB4LGludCB5KXsKICAgICAgICBpbnQgZCA9IDAsIHN0cCA9IDE7CiAgICAgICAgd2hpbGUoeCtzdHAtMSA8PSB5KXsKICAgICAgICAgICAgc3RwIDw8PSAxOwogICAgICAgICAgICArK2Q7CiAgICAgICAgfQogCiAgICAgICAgZCAtPSAxOwogICAgICAgIHN0cCA+Pj0gMTsKICAgICAgICByZXR1cm4gTWF0aC5taW4ocm1xRXZlbltkXVt4XSwgcm1xRXZlbltkXVt5LXN0cCsxXSk7CiAgICB9Cn07CiAKY2xhc3MgRmluZFBhbGluZHJvbWVTb2x2ZXIgewogICAgaW50W10gYWxsb3dlZDsKICAgIGludFtdIGxlbmd0aDsKICAgIFN0cmluZyBtc2c7CiAKICAgIHB1YmxpYyB2b2lkIHNvbHZlKCkgewogICAgICAgIE15U2Nhbm5lciBpbiA9IG5ldyBNeVNjYW5uZXIoKTsKICAgICAgICBvdXQgPSBuZXcgUHJpbnRXcml0ZXIobmV3IEJ1ZmZlcmVkT3V0cHV0U3RyZWFtKFN5c3RlbS5vdXQpKTsKIAogICAgICAgIG1zZyA9IGluLm5leHQoKTsKICAgICAgICBpbnQgbiA9IG1zZy5sZW5ndGgoKTsKIAogICAgICAgIGFsbG93ZWQgPSBuZXcgaW50W25dOwogICAgICAgIGxlbmd0aCA9IG5ldyBpbnRbbl07CiAKICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbjsgKytpKSB7CiAgICAgICAgICAgIGFsbG93ZWRbaV0gPSBpbi5uZXh0SW50KCk7CiAgICAgICAgICAgIGxlbmd0aFtpXSA9IDA7CiAgICAgICAgfQogCiAgICAgICAgTWFuYWNoZXIgbWFuYWNoZXIgPSBuZXcgTWFuYWNoZXIobik7CiAgICAgICAgbWFuYWNoZXIuYnVpbGQobXNnKTsKICAgICAgICBtYW5hY2hlci5idWlsZFJNUSgpOwogCiAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IG47ICsraSl7CiAgICAgICAgICAgIGludCBlbmRPZGQgPSBpICsgKGFsbG93ZWRbaV0tMSkvMjsKICAgICAgICAgICAgaW50IGVuZEV2ZW4gPSBpICsgYWxsb3dlZFtpXS8yOwogCiAgICAgICAgICAgIGludCBzdCA9IGksIGVuID0gZW5kT2RkOwogICAgICAgICAgICBpbnQgYW5zID0gLTE7CiAgICAgICAgICAgIHdoaWxlKHN0IDw9IGVuKXsKICAgICAgICAgICAgICAgIGludCBtaWQgPSAoc3QrZW4pLzI7CiAgICAgICAgICAgICAgICBpbnQgcmVzcG9uc2UgPSBtYW5hY2hlci5nZXRPZGQobWlkLGVuZE9kZCk7CiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgPD0gaSl7CiAgICAgICAgICAgICAgICAgICAgYW5zID0gbWlkOwogICAgICAgICAgICAgICAgICAgIHN0ID0gbWlkKzE7CiAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICBlbiA9IG1pZC0xOwogICAgICAgICAgICB9CiAKICAgICAgICAgICAgaWYgKGFucyAhPSAtMSkKICAgICAgICAgICAgICAgIGxlbmd0aFtpXSA9IE1hdGgubWF4KGxlbmd0aFtpXSwoYW5zLWkpKjIgKyAxKTsKIAogICAgICAgICAgICBzdCA9IGk7IGVuID0gZW5kRXZlbjsKICAgICAgICAgICAgYW5zID0gLTE7CiAgICAgICAgICAgIHdoaWxlKHN0IDw9IGVuKXsKICAgICAgICAgICAgICAgIGludCBtaWQgPSAoc3QrZW4pLzI7CiAgICAgICAgICAgICAgICBpbnQgcmVzcG9uc2UgPSBtYW5hY2hlci5nZXRFdmVuKG1pZCxlbmRFdmVuKTsKICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSA8PSBpKXsKICAgICAgICAgICAgICAgICAgICBhbnMgPSBtaWQ7CiAgICAgICAgICAgICAgICAgICAgc3QgPSBtaWQrMTsKICAgICAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgICAgIGVuID0gbWlkLTE7CiAgICAgICAgICAgIH0KIAogICAgICAgICAgICBpZiAoYW5zICE9IC0xKQogICAgICAgICAgICAgICAgbGVuZ3RoW2ldID0gTWF0aC5tYXgobGVuZ3RoW2ldLChhbnMtaSkqMik7CiAgICAgICAgfQogCiAgICAgICAgZm9yKGludCBpID0gMDsgaSA8IG47ICsraSkKICAgICAgICAgICAgb3V0LnByaW50KGxlbmd0aFtpXSArICIgIik7CiAKICAgICAgICBvdXQucHJpbnRsbigpOwogICAgICAgIG91dC5jbG9zZSgpOwogICAgfQogCiAgICAvLy0tLS0tLS0tLS0tUHJpbnRXcml0ZXIgZm9yIGZhc3RlciBvdXRwdXQtLS0tLS0tLS0tLS0tCiAgICBwdWJsaWMgc3RhdGljIFByaW50V3JpdGVyIG91dDsKIAogICAgLy8tLS0tLS0tLS0tLU15U2Nhbm5lciBjbGFzcyBmb3IgZmFzdGVyIGlucHV0LS0tLS0tLS0tLQogICAgcHVibGljIHN0YXRpYyBjbGFzcyBNeVNjYW5uZXIgewogICAgICAgIEJ1ZmZlcmVkUmVhZGVyIGJyOwogICAgICAgIFN0cmluZ1Rva2VuaXplciBzdDsKIAogICAgICAgIHB1YmxpYyBNeVNjYW5uZXIoKSB7CiAgICAgICAgICAgIGJyID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihTeXN0ZW0uaW4pKTsKICAgICAgICB9CiAKICAgICAgICBTdHJpbmcgbmV4dCgpIHsKICAgICAgICAgICAgd2hpbGUgKHN0ID09IG51bGwgfHwgIXN0Lmhhc01vcmVFbGVtZW50cygpKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcihici5yZWFkTGluZSgpKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzdC5uZXh0VG9rZW4oKTsKICAgICAgICB9CiAKICAgICAgICBpbnQgbmV4dEludCgpIHsKICAgICAgICAgICAgcmV0dXJuIEludGVnZXIucGFyc2VJbnQobmV4dCgpKTsKICAgICAgICB9CiAKICAgICAgICBsb25nIG5leHRMb25nKCkgewogICAgICAgICAgICByZXR1cm4gTG9uZy5wYXJzZUxvbmcobmV4dCgpKTsKICAgICAgICB9CiAKICAgICAgICBkb3VibGUgbmV4dERvdWJsZSgpIHsKICAgICAgICAgICAgcmV0dXJuIERvdWJsZS5wYXJzZURvdWJsZShuZXh0KCkpOwogICAgICAgIH0KIAogICAgICAgIFN0cmluZyBuZXh0TGluZSgpIHsKICAgICAgICAgICAgU3RyaW5nIHN0ciA9ICIiOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgc3RyID0gYnIucmVhZExpbmUoKTsKICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gc3RyOwogICAgICAgIH0KICAgIH0KfQ==