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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define PRIME1 99999883
#define PRIME2 99999893
#define EPS 0.00000001
#define NUM 48
using namespace std;

struct Info {
  Info() {
    for (int i = 0; i <= 25; i++)
      table[i] = 0;
  }
  ull table[26];
};

void strcpy(char *to, char *str) {
  for (int i = 0; str[i] != '\\0'; i++) {
    to[i] = str[i];
    to[i + 1] = '\\0';
  }
}

int main() {

  int length1, length2, left_length, right_length;

  char buf1[4001], buf2[4001], left_buf[4001], right_buf[4001];
  scanf("%s", buf1);
  scanf("%s", buf2);

  for (length1 = 0; buf1[length1] != '\\0'; length1++)
    ;
  for (length2 = 0; buf2[length2] != '\\0'; length2++)
    ;

  if (length1 <= length2) {
    left_length = length1;
    right_length = length2;
    strcpy(left_buf, buf1);
    strcpy(right_buf, buf2);
  } else {
    left_length = length2;
    right_length = length1;
    strcpy(left_buf, buf2);
    strcpy(right_buf, buf1);
  }

  bool FLG;
  if (left_length == 1) {
    FLG = false;
    for (int i = 0; i < right_length; i++) {
      if (right_buf[i] == left_buf[0]) {
        FLG = true;
        break;
      }
    }
    if (FLG) {
      printf("1\\n");
    } else {
      printf("0\\n");
    }

    return 0;
  }

  Info info_left[4005], info_right[4005];

  for (left_length = 0; left_buf[left_length] != '\\0'; left_length++) {
    info_left[left_length + 1].table[left_buf[left_length] - 97]++;
    for (int i = 0; i <= 25; i++) {
      info_left[left_length + 2].table[i] = info_left[left_length + 1].table[i];
    }
  }

  for (right_length = 0; right_buf[right_length] != '\\0'; right_length++) {
    info_right[right_length + 1].table[right_buf[right_length] - 97]++;
    for (int i = 0; i <= 25; i++) {
      info_right[right_length + 2].table[i] =
          info_right[right_length + 1].table[i];
    }
  }

  // left <= right

  vector<ull> V[left_length + 1];
  ull calcTable[26], calcHash[27], hashValue;

  for (int left = 0; left < right_length; left++) {
    for (int right = left; right < right_length; right++) {
      if (right - left + 1 > left_length)
        break;

      calcHash[0] = 0;

      for (int i = 0; i <= 25; i++) {
        calcTable[i] =
            info_right[right + 1].table[i] - info_right[left].table[i] + 1;
        calcHash[i + 1] = calcTable[i] + calcHash[i] * MOD;
      }

      hashValue = calcHash[26];

      V[right - left + 1].push_back(hashValue);
    }
  }

  int maximum = 0;

  for (int i = 1; i <= left_length; i++)
    sort(V[i].begin(), V[i].end());

  int search_left, search_right, m, tmp_len;

  for (int left = 0; left < left_length; left++) {
    for (int right = left_length - 1; right >= left; right--) {
      if (right - left + 1 <= maximum)
        break;

      calcHash[0] = 0;

      for (int i = 0; i <= 25; i++) {
        calcTable[i] =
            info_left[right + 1].table[i] - info_left[left].table[i] + 1;
        calcHash[i + 1] = calcTable[i] + calcHash[i] * MOD;
      }

      hashValue = calcHash[26];

      tmp_len = right - left + 1;
      search_left = 0, search_right = V[tmp_len].size() - 1;
      m = (search_left + search_right) / 2;

      while (search_left <= search_right) {
        if (V[tmp_len][m] == hashValue) {
          maximum = max(maximum, tmp_len);
          break;
        } else {
          if (V[tmp_len][m] < hashValue) {
            search_left = m + 1;
          } else {
            search_right = m - 1;
          }
        }
        m = (search_left + search_right) / 2;
      }
    }
  }

  printf("%d\\n", maximum);

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <stdio.h>
#include <vector>
typedef long long int ll;
#define BIG_NUM 2000000000
using namespace std;

struct Info {
  Info() {
    for (int i = 0; i <= 25; i++)
      table[i] = 0;
  }
  int table[26];
};

void strcpy(char *to, char *str) {
  for (int i = 0; str[i] != '\\0'; i++) {
    to[i] = str[i];
    to[i + 1] = '\\0';
  }
}

int main() {

  int length1, length2, left_length, right_length, left_start, left_end,
      right_start, right_end;

  char buf1[4001], buf2[4001], left_buf[4001], right_buf[4001];
  scanf("%s", buf1);
  scanf("%s", buf2);

  for (length1 = 0; buf1[length1] != '\\0'; length1++)
    ;
  for (length2 = 0; buf2[length2] != '\\0'; length2++)
    ;

  if (length1 <= length2) {
    left_length = length1;
    right_length = length2;
    strcpy(left_buf, buf1);
    strcpy(right_buf, buf2);
  } else {
    left_length = length2;
    right_length = length1;
    strcpy(left_buf, buf2);
    strcpy(right_buf, buf1);
  }

  bool FLG;
  if (left_length == 1) {
    FLG = false;
    for (int i = 0; i < right_length; i++) {
      if (right_buf[i] == left_buf[0]) {
        FLG = true;
        break;
      }
    }
    if (FLG) {
      printf("1\\n");
    } else {
      printf("0\\n");
    }

    return 0;
  }

  int check_fix[26], check_move[26];
  Info info_left[4005], info_right[4005];

  //?´??????????????????????????????????
  for (left_length = 0; left_buf[left_length] != '\\0'; left_length++) {
    info_left[left_length + 1].table
        [left_buf[left_length] -
         97]++; //??????????´?????????????????????????????????????info???1?????????????????????!!!?????????
    for (int i = 0; i <= 25; i++) {
      info_left[left_length + 2].table[i] = info_left[left_length + 1].table[i];
    }
  }

  for (right_length = 0; right_buf[right_length] != '\\0'; right_length++) {
    info_right[right_length + 1].table[right_buf[right_length] - 97]++;
    for (int i = 0; i <= 25; i++) {
      info_right[right_length + 2].table[i] =
          info_right[right_length + 1].table[i];
    }
  }

  int maximum = 0;

  // left???????????¨right???????????????????????§
  for (right_end = 1; right_end <= left_length; right_end++) {
    left_start = left_length - right_end;
    for (int a = 0; left_start + a < left_length - 1;
         a++) { //?????????????????????????????????
      for (int b = a + 1; left_start + b < left_length;
           b++) { //?????????????????????????????????
        FLG = true;
        for (
            int i = 0; i <= 25;
            i++) { //???info????????????????????????1????????????????????¨?????¨???!!!!???
          check_move[i] = info_left[left_start + b + 1].table[i] -
                          info_left[left_start + a].table[i];
          check_fix[i] = info_right[b + 1].table[i] - info_right[a].table[i];
          if (check_move[i] != check_fix[i]) {
            FLG = false;
            break;
          }
        }
        if (FLG) {
          maximum = max(maximum, b - a + 1);
        }
      }
    }
  }

  // left???????????¨right???????????????????????§
  for (right_end = left_length; right_end < right_length; right_end++) {
    right_start = right_end - left_length;
    for (int a = 0; a < left_length - 1;
         a++) { //?????????????????????????????????
      for (int b = a + 1; b < left_length;
           b++) { //?????????????????????????????????
        FLG = true;
        for (int i = 0; i <= 25; i++) {
          check_move[i] = info_left[b + 1].table[i] - info_left[a].table[i];
          check_fix[i] = info_right[right_start + b + 1].table[i] -
                         info_right[right_start + a].table[i];
          if (check_move[i] != check_fix[i]) {
            FLG = false;
            break;
          }
        }
        if (FLG) {
          maximum = max(maximum, b - a + 1);
        }
      }
    }
  }

  // left_end???0??????????????§
  for (left_end = left_length - 1; left_end >= 1; left_end--) {
    right_start = right_length - left_end;
    for (int a = 0; a < left_end - 1; a++) {
      for (int b = a + 1; b < left_end; b++) {
        FLG = true;
        for (int i = 0; i <= 25; i++) {
          check_move[i] = info_left[b + 1].table[i] - info_left[a].table[i];
          check_fix[i] = info_right[right_start + b + 1].table[i] -
                         info_right[right_start + a].table[i];
          if (check_move[i] != check_fix[i]) {
            FLG = false;
            break;
          }
        }
        if (FLG) {
          maximum = max(maximum, b - a + 1);
        }
      }
    }
  }

  printf("%d\\n", maximum);

  return 0;
}