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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
#define eps 1e-10
using namespace std;
int a[100005], sum[100005], md[100006];
map<int, int> m;
int cnt[100005], tot;
main() {
  int N, S, W, Q;
  while (scanf("%d%d%d%d", &N, &S, &W, &Q), N + S + W + Q) {
    memset(cnt, 0, sizeof(cnt));
    tot = 0;
    m.clear();
    int g = S;
    for (int i = 0; i < N; i++) {
      a[i] = (g / 7) % 10;
      if (g % 2 == 0) {
        g = (g / 2);
      } else {
        g = (g / 2) ^ W;
      }
    }
    if (Q == 2 || Q == 5) {
      int cur = 0, ans = 0;
      for (int i = 0; i < N; i++) {
        if (a[i] != 0)
          cur++;
        if (a[i] % Q == 0)
          ans += cur;
      }
      printf("%d\\n", ans);
      continue;
    }
    for (int i = 0; i < N / 2; i++)
      swap(a[i], a[N - 1 - i]);
    md[0] = 1;
    for (int i = 1; i < 100005; i++)
      md[i] = md[i - 1] * 10 % Q;
    sum[0] = a[0] % Q;
    m[sum[0]] = ++tot;
    for (int i = 1; i < N; i++) {
      sum[i] = (a[i] * md[i] + sum[i - 1]) % Q;
      if (m[sum[i]] == 0)
        m[sum[i]] = ++tot;
    }
    int ans = 0;
    for (int i = N - 1; i >= 0; i--) {
      ans += cnt[m[sum[i]]];
      if (a[i] != 0)
        cnt[m[sum[i]]]++;
    }
    ans += cnt[m[0]];
    cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
inline int Input() {
  int ret = 0;
  bool isN = 0;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-')
      isN = 1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    ret = ret * 10 + c - '0';
    c = getchar();
  }
  return isN ? -ret : ret;
}

inline void Output(long long x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  int len = 0, data[20];
  while (x) {
    data[len++] = x % 10;
    x /= 10;
  }
  if (!len)
    data[len++] = 0;
  while (len--)
    putchar(data[len] + 48);
  putchar('\\n');
}
#pragma comment(linker, "/STACK:124000000,124000000")
#include <map>
#include <queue>
#include <vector>
#define eps 1e-10
#define INF 2000000009
#define maxn 150050
#define maxm 2500010
#define mod 1000000
#define llINF 1LL << 60
using namespace std;

struct SHIT {
  int num;
  int da;
} q[2][10000007];
map<int, int> mp;
int a[100005];
int main() {
  int n, s, w, Q;
  while (scanf("%d%d%d%d", &n, &s, &w, &Q) && n) {
    for (int i = 0; i < n; i++) {
      a[i] = (s / 7) % 10;
      if (s & 1) {
        s = (s / 2) ^ w;
      } else {
        s = s / 2;
      }
    }
    //        for(int i=0;i<n;i++)
    //            printf("%d",a[i]);
    //        printf("\\n");
    int ans = 0;
    int cnt = 0, tcnt;
    int flag = 0;
    q[flag][1].num = 1;
    q[flag][1].da = 0;
    int i = 0;
    while (a[i] == 0 && i < n)
      i++;
    for (i; i < n; i++) {
      flag = 1 - flag;
      mp.clear();
      tcnt = 0;
      for (int j = 1; j <= cnt; j++) {
        int t = (q[1 - flag][j].da * 10 + a[i]) % Q;
        if (t == 0)
          ans += q[1 - flag][j].num;
        if (mp[t]) {
          q[flag][mp[t]].num += q[1 - flag][j].num;
        } else {
          tcnt++;
          mp[t] = tcnt;
          q[flag][tcnt].da = t;
          q[flag][tcnt].num = q[1 - flag][j].num;
        }
      }
      if (a[i] != 0) {
        int t = a[i] % Q;
        if (t == 0)
          ans += 1;
        if (mp[t]) {
          q[flag][mp[t]].num += 1;
        } else {
          tcnt++;
          mp[t] = tcnt;
          q[flag][tcnt].da = t;
          q[flag][tcnt].num = 1;
        }
      }
      //            for(int j=1;j<=tcnt;j++)
      //                printf("%d %d\\n",q[flag][j].num,q[flag][j].da);
      //            printf("ss\\n");
      cnt = tcnt;
      // printf("%d %d\\n",cnt,ans);
    }
    printf("%d\\n", ans);
  }
  return 0;
}