fork download
  1.  
  2. import java.io.*;
  3.  
  4. public class Main {
  5.  
  6. static class EntradaRapida {
  7. private final BufferedInputStream entrada =
  8.  
  9. private final byte[] datos = new byte[1 << 16];
  10. private int pos = 0;
  11. private int longitud = 0;
  12.  
  13. private int leer() throws IOException {
  14. if (pos >= longitud) {
  15. longitud = entrada.read(datos);
  16. pos = 0;
  17.  
  18. if (longitud <= 0) return -1;
  19. }
  20.  
  21. return datos[pos++];
  22. }
  23.  
  24. int leerEntero() throws IOException {
  25. int caracter;
  26.  
  27. do {
  28. caracter = leer();
  29. if (caracter == -1) return -1;
  30. } while (caracter <= 32);
  31.  
  32. int valor = 0;
  33.  
  34. while (caracter > 32) {
  35. valor = valor * 10 + caracter - '0';
  36. caracter = leer();
  37. }
  38.  
  39. return valor;
  40. }
  41.  
  42. String leerCadena() throws IOException {
  43. StringBuilder cadenaLeida = new StringBuilder();
  44. int caracter;
  45.  
  46. do {
  47. caracter = leer();
  48. if (caracter == -1) return null;
  49. } while (caracter <= 32);
  50.  
  51. while (caracter > 32) {
  52. cadenaLeida.append((char) caracter);
  53. caracter = leer();
  54. }
  55.  
  56. return cadenaLeida.toString();
  57. }
  58.  
  59. char leerLetra() throws IOException {
  60. int caracter;
  61.  
  62. do {
  63. caracter = leer();
  64. } while (caracter <= 32 && caracter != -1);
  65.  
  66. return (char) caracter;
  67. }
  68. }
  69.  
  70. static class ArbolSegmentos {
  71. private final int inicioArbol;
  72. private final int[] segmentos;
  73.  
  74. ArbolSegmentos(char[] letras) {
  75. int longitud = letras.length;
  76. int capacidad = 1;
  77.  
  78. while (capacidad < longitud) {
  79. capacidad <<= 1;
  80. }
  81.  
  82. inicioArbol = capacidad;
  83. segmentos = new int[inicioArbol << 1];
  84.  
  85. construir(letras);
  86. }
  87.  
  88. private void construir(char[] letras) {
  89. for (int i = 0; i < letras.length; i++) {
  90. segmentos[inicioArbol + i] =
  91. 1 << (letras[i] - 'a');
  92. }
  93.  
  94. for (int actual = inicioArbol - 1; actual > 0; actual--) {
  95. segmentos[actual] = segmentos[actual << 1] |
  96. segmentos[actual << 1 | 1];
  97. }
  98. }
  99.  
  100. void actualizar(int indice, char nuevoCaracter) {
  101. int actual = inicioArbol + indice;
  102.  
  103. segmentos[actual] = 1 << (nuevoCaracter - 'a');
  104.  
  105. for (actual >>= 1; actual > 0; actual >>= 1) {
  106. segmentos[actual] = segmentos[actual << 1] |
  107. segmentos[actual << 1 | 1];
  108. }
  109. }
  110.  
  111. int consultar(int inicio, int fin) {
  112. int letrasPresentes = 0;
  113.  
  114. inicio += inicioArbol;
  115. fin += inicioArbol + 1;
  116.  
  117. while (inicio < fin) {
  118.  
  119. if ((inicio & 1) != 0) {
  120. letrasPresentes |= segmentos[inicio++];
  121. }
  122.  
  123. if ((fin & 1) != 0) {
  124. letrasPresentes |= segmentos[--fin];
  125. }
  126.  
  127. inicio >>= 1;
  128. fin >>= 1;
  129. }
  130.  
  131. return Integer.bitCount(letrasPresentes);
  132. }
  133. }
  134.  
  135. static void resolver(EntradaRapida entrada) throws IOException {
  136.  
  137. String cadenaInicial = entrada.leerCadena();
  138.  
  139. if (cadenaInicial == null) return;
  140.  
  141. char[] caracteres = cadenaInicial.toCharArray();
  142.  
  143. int totalConsultas = entrada.leerEntero();
  144.  
  145. ArbolSegmentos estructura = new ArbolSegmentos(caracteres);
  146.  
  147. StringBuilder salida = new StringBuilder();
  148.  
  149. for (int consulta = 0; consulta < totalConsultas; consulta++) {
  150.  
  151. int operacion = entrada.leerEntero();
  152.  
  153. if (operacion == 1) {
  154.  
  155. int indice = entrada.leerEntero() - 1;
  156. char nuevoCaracter = entrada.leerLetra();
  157.  
  158. if (caracteres[indice] != nuevoCaracter) {
  159. caracteres[indice] = nuevoCaracter;
  160. estructura.actualizar(indice, nuevoCaracter);
  161. }
  162.  
  163. } else {
  164.  
  165. int inicio = entrada.leerEntero() - 1;
  166. int fin = entrada.leerEntero() - 1;
  167.  
  168. salida.append(
  169. estructura.consultar(inicio, fin)
  170. ).append('\n');
  171. }
  172. }
  173.  
  174. System.out.print(salida);
  175. }
  176.  
  177. public static void main(String[] args) throws IOException {
  178. resolver(new EntradaRapida());
  179. }
  180. }
Success #stdin #stdout 0.07s 52708KB
stdin
Standard input is empty
stdout
Standard output is empty