fork download
  1. /**
  2.  *
  3.  * @author chang
  4.  * created on 20/02/15
  5.  */
  6.  
  7. import java.util.*;
  8. import java.io.*;
  9.  
  10. class FindPalindrome {
  11. public static void main(String[] args) {
  12. FindPalindromeSolver ob = new FindPalindromeSolver();
  13. ob.solve();
  14. }
  15. }
  16.  
  17. class Manacher{
  18. int[] odd,even;
  19. int[][] rmqEven, rmqOdd;
  20. int n;
  21.  
  22. Manacher(int size){
  23. n = size;
  24. even = new int[n];
  25. odd = new int[n];
  26. rmqEven = new int[20][n];
  27. rmqOdd = new int[20][n];
  28. }
  29.  
  30. /**
  31.   * builds for odd and even length
  32.   * for odd actual length of palindrome at center i is odd[i]+1
  33.   */
  34. void build(String msg){
  35. int st = 0,en = -1;
  36.  
  37. for(int i = 0; i < n; ++i){
  38. int dR = en-i, size = 1;
  39. if (en >= i)
  40. size += Math.min(dR,odd[st+dR]);
  41. while(i-size >= 0 && i+size < n && msg.charAt(i+size) == msg.charAt(i-size))
  42. ++size;
  43. size -= 1;
  44. odd[i] = size;
  45. if (i+size > en) {
  46. en = i + size;
  47. st = i - size;
  48. }
  49. }
  50.  
  51. st = 0;
  52. en = -1;
  53. for(int i = 0; i < n; ++i){
  54. int dR = en-i, size = 1;
  55. if (en >= i)
  56. size += Math.min(dR+1,even[st+dR+1]);
  57. while(i-size >= 0 && i+size-1 < n && msg.charAt(i+size-1) == msg.charAt(i-size))
  58. ++size;
  59. size -= 1;
  60. even[i] = size;
  61. if (i+size-1 > en){
  62. en = i+size-1;
  63. st = i-size;
  64. }
  65. }
  66. }
  67.  
  68. /**
  69.   * build the min rmq for starting point of palindrome
  70.   * centered at i
  71.   */
  72. void buildRMQ(){
  73. for(int i = 0; i < n; ++i){
  74. rmqOdd[0][i] = i-odd[i];
  75. rmqEven[0][i] = i-even[i];
  76. }
  77.  
  78. for(int h = 1, step = 1; (1 << h) < n; ++h, step <<= 1){
  79. for(int i = 0; i < n; ++i){
  80. if ((i+(1 << h)) >= n)
  81. continue;
  82. rmqOdd[h][i] = Math.min(rmqOdd[h-1][i],rmqOdd[h-1][i+step]);
  83. rmqEven[h][i] = Math.min(rmqEven[h-1][i],rmqEven[h-1][i+step]);
  84. }
  85. }
  86. }
  87.  
  88. int getOdd(int x,int y){
  89. int d = 0, stp = 1;
  90. while(x+stp-1 <= y){
  91. stp <<= 1;
  92. ++d;
  93. }
  94.  
  95. d -= 1;
  96. stp >>= 1;
  97. return Math.min(rmqOdd[d][x], rmqOdd[d][y-stp+1]);
  98. }
  99.  
  100. int getEven(int x,int y){
  101. int d = 0, stp = 1;
  102. while(x+stp-1 <= y){
  103. stp <<= 1;
  104. ++d;
  105. }
  106.  
  107. d -= 1;
  108. stp >>= 1;
  109. return Math.min(rmqEven[d][x], rmqEven[d][y-stp+1]);
  110. }
  111. };
  112.  
  113. class FindPalindromeSolver {
  114. int[] allowed;
  115. int[] length;
  116. String msg;
  117.  
  118. public void solve() {
  119. MyScanner in = new MyScanner();
  120.  
  121. msg = in.next();
  122. int n = msg.length();
  123.  
  124. allowed = new int[n];
  125. length = new int[n];
  126.  
  127. for(int i = 0; i < n; ++i) {
  128. allowed[i] = in.nextInt();
  129. length[i] = 0;
  130. }
  131.  
  132. Manacher manacher = new Manacher(n);
  133. manacher.build(msg);
  134. manacher.buildRMQ();
  135.  
  136. for(int i = 0; i < n; ++i){
  137. int endOdd = i + (allowed[i]-1)/2;
  138. int endEven = i + allowed[i]/2;
  139.  
  140. int st = i, en = endOdd;
  141. int ans = -1;
  142. while(st <= en){
  143. int mid = (st+en)/2;
  144. int response = manacher.getOdd(mid,endOdd);
  145. if (response <= i){
  146. ans = mid;
  147. st = mid+1;
  148. } else
  149. en = mid-1;
  150. }
  151.  
  152. if (ans != -1)
  153. length[i] = Math.max(length[i],(ans-i)*2 + 1);
  154.  
  155. st = i; en = endEven;
  156. ans = -1;
  157. while(st <= en){
  158. int mid = (st+en)/2;
  159. int response = manacher.getEven(mid,endEven);
  160. if (response <= i){
  161. ans = mid;
  162. st = mid+1;
  163. } else
  164. en = mid-1;
  165. }
  166.  
  167. if (ans != -1)
  168. length[i] = Math.max(length[i],(ans-i)*2);
  169. }
  170.  
  171. for(int i = 0; i < n; ++i)
  172. out.print(length[i] + " ");
  173.  
  174. out.println();
  175. out.close();
  176. }
  177.  
  178. //-----------PrintWriter for faster output-------------
  179. public static PrintWriter out;
  180.  
  181. //-----------MyScanner class for faster input----------
  182. public static class MyScanner {
  183.  
  184. public MyScanner() {
  185. }
  186.  
  187. String next() {
  188. while (st == null || !st.hasMoreElements()) {
  189. try {
  190. st = new StringTokenizer(br.readLine());
  191. } catch (IOException e) {
  192. e.printStackTrace();
  193. }
  194. }
  195. return st.nextToken();
  196. }
  197.  
  198. int nextInt() {
  199. return Integer.parseInt(next());
  200. }
  201.  
  202. long nextLong() {
  203. return Long.parseLong(next());
  204. }
  205.  
  206. double nextDouble() {
  207. return Double.parseDouble(next());
  208. }
  209.  
  210. String nextLine() {
  211. String str = "";
  212. try {
  213. str = br.readLine();
  214. } catch (IOException e) {
  215. e.printStackTrace();
  216. }
  217. return str;
  218. }
  219. }
  220. }
Runtime error #stdin #stdout #stderr 0.1s 320320KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Exception in thread "main" java.lang.NullPointerException
	at java.util.StringTokenizer.<init>(StringTokenizer.java:199)
	at java.util.StringTokenizer.<init>(StringTokenizer.java:236)
	at FindPalindromeSolver$MyScanner.next(Main.java:194)
	at FindPalindromeSolver.solve(Main.java:122)
	at FindPalindrome.main(Main.java:13)