Problem p02248 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <iostream>
#include <stdio.h>

using namespace std;

int move_length[128], most_right_index;

void decideMoveLength(int compressedP[], int length, int most_right) {
  int j, calc_right_index;

  for (j = 0; j < 3; j++) {
    if (compressedP[length - 1 - j] == most_right &&
        compressedP[length - 2 - j] != -1)
      break;
  }
  most_right_index = length - 1 - j;

  if (length > 2 && compressedP[length - 1] == compressedP[length - 2] &&
      compressedP[length - 2] != compressedP[length - 3]) {
    move_length[most_right] = 1;
    calc_right_index = length - 2;
  } else if (length > 2 && compressedP[length - 1] == compressedP[length - 2] &&
             compressedP[length - 2] == compressedP[length - 3]) {
    move_length[most_right] = 1;
    calc_right_index = length - 3;
  } else {
    calc_right_index = most_right_index;
  }

  for (int i = length - j - 2; i >= 0; i--) {
    if (i == 0 || (compressedP[i - 1] != -1 && compressedP[i] >= 48 &&
                   compressedP[i] <= 122)) {
      if (move_length[compressedP[i]] == -1) {
        move_length[compressedP[i]] = calc_right_index - i;
      }
    }
  }

  for (int i = 0; i < 128; i++) {
    if (move_length[i] == -1) {
      move_length[i] = most_right_index + 1;
    }
  }
}

int compress(int compressed_array[], char base_array[],
             int &compressed_length) {

  int comp_index = 0, count = 0, length = 0;
  char ch = base_array[0];
  for (int i = 0; base_array[i] != '\\0';) {

    if (ch == base_array[i]) {
      count++;
      if (base_array[i + 1] == '\\0') {
        if (count >= 4) {
          compressed_array[comp_index - 2] = -1;
          compressed_array[comp_index - 1] = count;
        } else {
          compressed_array[comp_index++] = ch;
        }
      } else {
        if (count <= 3) {
          compressed_array[comp_index++] = ch;
        }
      }
      i++;
      length++;
    } else {
      if (count >= 4) {
        compressed_array[comp_index - 2] = -1;
        compressed_array[comp_index - 1] = count;
      }
      count = 0;
      ch = base_array[i];
    }
  }
  compressed_length = comp_index;
  return length;
}

int main() {
  int T_length, P_length, T_comp_index, P_comp_index, comp_P_length,
      comp_T_length, tmp;

  for (int i = 0; i < 128; i++)
    move_length[i] = -1;

  char *T = new char[1000001];
  int *compressedT = new int[1000001];

  char P[10001];
  int compressedP[10001];

  scanf("%s", T);
  scanf("%s", P);

  T_length = compress(compressedT, T, comp_T_length);
  P_length = compress(compressedP, P, comp_P_length);

  int *total_count = new int[comp_T_length];
  int sum = 0;
  for (int i = 0; i < comp_T_length; i++) {
    if ((i > 0 && compressedT[i - 1] != -1 && compressedT[i] != -1) || i == 0) {
      total_count[i] = sum;
      sum++;
    } else if (i > 0 && compressedT[i - 1] == -1) {
      sum += (compressedT[i] - 2);
      total_count[i] = sum;
      sum++;
    }
  }

  bool multFLG = false, leftsuceedFLG = false, rightsucceedFLG = false;
  int most_left = compressedP[0], most_right = compressedP[0];
  for (int i = 1; i < comp_P_length; i++) {
    if (compressedP[i - 1] != -1 && compressedP[i] != -1) {
      most_right = compressedP[i];
      if (compressedP[i] != most_left) {
        multFLG = true;
      }
    }
  }

  if (comp_P_length > 2 && compressedP[comp_P_length - 2] == -1) {
    rightsucceedFLG = true;
  }

  if (comp_P_length > 1 && compressedP[1] == -1)
    leftsuceedFLG = true;

  decideMoveLength(compressedP, comp_P_length, most_right);

  if (multFLG) {

    for (T_comp_index = 0; T_comp_index < comp_T_length &&
                           compressedT[T_comp_index] != most_right;
         T_comp_index++)
      ;

    if (T_comp_index == comp_T_length)
      return 0;

    int outputFLG;

    while (T_comp_index < comp_T_length) {
      tmp = T_comp_index;
      P_comp_index = comp_P_length - 1;
      outputFLG = 0;
      while (P_comp_index >= 0) {

        if (tmp == T_comp_index) {
          if (rightsucceedFLG) {
            if ((tmp < comp_T_length - 2) && (compressedT[tmp + 1] == -1) &&
                (compressedT[tmp + 2] >= compressedP[comp_P_length - 1])) {
              tmp -= 1;
              P_comp_index -= 3;
            } else {
              break;
            }
          } else {
            if ((tmp < comp_T_length - 2) && (compressedT[tmp + 1] == -1)) {
              if (compressedP[P_comp_index] != compressedP[P_comp_index - 1]) {
                tmp--;
                P_comp_index--;
              } else if ((compressedP[P_comp_index] ==
                          compressedP[P_comp_index - 1]) &&
                         (compressedP[P_comp_index - 1] !=
                          compressedP[P_comp_index - 2])) {
                tmp--;
                P_comp_index -= 2;
              } else {
                tmp--;
                P_comp_index -= 3;
              }
            } else {
              tmp--;
              P_comp_index--;
            }
          }
        } else if (leftsuceedFLG && P_comp_index == 2) {
          if ((tmp > 1) && (compressedT[tmp - 1] == -1) &&
              (compressedT[tmp] >= compressedP[P_comp_index])) {
            tmp -= 3;
            P_comp_index -= 3;
            outputFLG = 2;
          } else {
            break;
          }
        } else if ((leftsuceedFLG == false) && (P_comp_index == 2) &&
                   (compressedP[2] == compressedP[1]) &&
                   (compressedP[1] == compressedP[0])) {

          if ((tmp >= 2) && (compressedT[tmp - 1] == -1) &&
              (compressedT[tmp - 2] == compressedP[0])) {

            tmp -= 3;
            P_comp_index -= 3;
            outputFLG = 3;
          } else if (compressedP[P_comp_index] == compressedT[tmp] && tmp > 1 &&
                     compressedT[tmp] == compressedT[tmp - 1] &&
                     compressedT[tmp - 1] == compressedT[tmp - 2]) {
            tmp -= 3;
            P_comp_index -= 3;

          } else {
            break;
          }

        } else if ((leftsuceedFLG == false) && (P_comp_index == 1) &&
                   (compressedP[1] == compressedP[0])) {

          if ((tmp >= 2) && (compressedT[tmp - 1] == -1) &&
              (compressedT[tmp - 2] == compressedP[0])) {
            tmp -= 3;
            P_comp_index -= 2;
            outputFLG = 3;
          } else if ((compressedP[P_comp_index] == compressedT[tmp]) &&
                     (tmp > 0) && (compressedT[tmp - 1] != -1) &&
                     (compressedT[tmp - 2] != -1) &&
                     (compressedT[tmp] == compressedT[tmp - 1])) {
            tmp -= 2;
            P_comp_index -= 2;
          } else {
            break;
          }

        } else if ((leftsuceedFLG == false) && (P_comp_index == 0) &&
                   (tmp >= 2) && (compressedT[tmp - 1] == -1) &&
                   (compressedT[tmp - 2] == compressedP[P_comp_index])) {
          tmp -= 3;
          P_comp_index--;
          outputFLG = 3;
        } else {
          if (compressedP[P_comp_index] == compressedT[tmp]) {
            tmp -= 1;
            P_comp_index--;
          } else {
            break;
          }
        }
      }

      if (P_comp_index == -1) {
        switch (outputFLG) {
        case 0:
          printf("%d\\n", total_count[tmp + 1]);
          break;
        case 2:
          printf("%d\\n",
                 total_count[tmp + 1] + compressedT[tmp + 3] - compressedP[2]);
          break;
        case 3:
          if (compressedP[0] != compressedP[1]) {
            printf("%d\\n", total_count[tmp + 1] + compressedT[tmp + 3] - 1);
          } else if (compressedP[0] == compressedP[1] &&
                     compressedP[0] != compressedP[2]) {
            printf("%d\\n", total_count[tmp + 1] + compressedT[tmp + 3] - 2);
          } else {
            printf("%d\\n", total_count[tmp + 1] + compressedT[tmp + 3] - 3);
          }
          break;
        }
      }

      T_comp_index += move_length[compressedT[T_comp_index]];

      while (true) {

        if (T_comp_index >= comp_T_length) {
          break;
        } else if (compressedT[T_comp_index - 1] != -1 &&
                   compressedT[T_comp_index] == most_right) {
          break;
        } else {
          if (compressedT[T_comp_index] == -1) {
            T_comp_index += 2;
          } else if (compressedT[T_comp_index - 1] == -1) {
            T_comp_index += 1;
          } else {
            T_comp_index += move_length[compressedT[T_comp_index]];
          }
        }
      }
    }

  } else {
    int div = 0;
    if (rightsucceedFLG) {
      for (int i = 0; i < comp_T_length;) {
        if (compressedT[i] == most_right && i < comp_T_length - 2 &&
            compressedT[i + 1] == -1 &&
            compressedT[i + 2] >= compressedP[comp_P_length - 1]) {
          int t_s = compressedT[i + 2];
          int p_s = compressedP[comp_P_length - 1];
          for (int k = 0; p_s + k <= t_s; k++) {
            printf("%d\\n", total_count[i] + k);
          }
        }
        for (div = 1; i + div < comp_T_length; div++) {
          if (compressedT[i + div] == most_right &&
              i + div < comp_T_length - 2 &&
              compressedT[i + div + 2] >= compressedP[comp_P_length - 1]) {
            break;
          }
        }
        i += div;
      }
    } else {
      for (int i = 0; i < comp_T_length;) {
        if (compressedT[i] == most_right && i < comp_T_length - 2 &&
            compressedT[i + 1] == -1 && compressedT[i + 2] >= comp_P_length) {
          int t_s = compressedT[i + 2];
          int p_s = comp_P_length;
          for (int k = 0; p_s + k <= t_s; k++) {
            printf("%d\\n", total_count[i] + k);
          }
        } else if (compressedT[i] == most_right) {
          if (comp_P_length == 1) {
            printf("%d\\n", total_count[i]);
          } else if (comp_P_length == 2 && i < comp_T_length - 1 &&
                     compressedT[i + 1] == most_right) {
            printf("%d\\n", total_count[i]);
          } else if (comp_P_length == 3 && i < comp_T_length - 2 &&
                     compressedT[i + 1] == most_right &&
                     compressedT[i + 2] == most_right) {
            printf("%d\\n", total_count[i]);
          }
        }

        for (div = 1; i + div < comp_T_length; div++) {
          if (compressedT[i + div] == most_right &&
              i + div < comp_T_length - 2 &&
              compressedT[i + div + 2] >= comp_P_length) {
            break;
          } else if (compressedT[i + div] == most_right) {
            break;
          }
        }
        i += div;
      }
    }
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <stdio.h>

using namespace std;

int move_length[128];

void decideMoveLength(char P[], int length) {
  char most_right = P[length - 1];
  move_length[most_right] = length;
  for (int i = length - 2; i >= 0; i--) {
    if (P[i] == most_right && move_length[most_right] == length) {
      move_length[most_right] = length - (i + 1);
    } else {
      if (move_length[P[i]] == -1) {
        move_length[P[i]] = length - (i + 1);
      }
    }
  }

  for (int i = 0; i < 128; i++) {
    if (move_length[i] == -1)
      move_length[i] = length;
  }
}

int main() {
  int T_length = 0, P_length = 0, T_index, P_index, tmp;

  for (int i = 0; i < 128; i++)
    move_length[i] = -1;

  char *T = new char[1000001];
  char P[10001];

  scanf("%s", T);
  scanf("%s", P);

  for (int i = 0; T[i] != '\\0'; i++)
    T_length++;
  for (int i = 0; P[i] != '\\0'; i++)
    P_length++;

  decideMoveLength(P, P_length);

  T_index = P_length - 1;
  P_index = P_length - 1;
  while (T_index <= T_length - 1) {
    tmp = T_index;
    while (T[tmp] == P[P_index] && P_index >= 0) {
      tmp--;
      P_index--;
    };
    if (P_index == -1) {
      printf("%d\\n", tmp + 1);
      T_index++;
    } else {
      T_index += move_length[T[T_index]];
    }
    P_index = P_length - 1;
  }
}