Problem p03974 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#define debug(x) cerr << #x << " = " << x << endl;

#define mod 1000000007              // 1e9+7(prime number)
#define INF 1000000000              // 1e9
#define LLINF 2000000000000000000LL // 2e18
#define SIZE 100010

int pp[26];

/* Trie */

struct Trie {
  int val;
  int val2;
  int depth;
  Trie *next[26];
  Trie *warp, *warp_back, *back;

  Trie() : val(0), val2(0), warp_back(this), back(this) {
    memset(next, 0, sizeof(next));
  }

  void insert(string &s, int i = 0) {
    val++; // 接頭辞のカウント
    depth = i;

    if (s[i]) {
      int al = s[i] - 'a';

      if (next[al] == NULL) {
        next[al] = new Trie;
        next[al]->warp = NULL;
      }

      next[al]->insert(s, i + 1);
    } else {
      val2++; // 終端のカウント
    }
  }

  int find(string &s, int last_val = INF) {
    int ret = 0;

    if (val == 1)
      return 0;

    if (val == last_val) {
      warp_back = back->warp_back;
      back->warp_back->warp = this;
    }

    if (warp && warp != this) {
      return warp->find(s, val);
    }

    if (s[depth]) {
      int al = s[depth] - 'a';

      for (int j = 0; pp[j] != al; j++) {
        if (next[pp[j]])
          ret += next[pp[j]]->val;
      }

      if (next[al])
        return ret + val2 + next[al]->find(s, val);
      else
        return ret + val2;

    } else {
      return 0;
    }
  }
};

int main() {
  int n, q;
  char in[400001];
  string s[SIZE];
  Trie trie;

  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%s", in);
    s[i] = in;
    trie.insert(s[i]);
  }

  scanf("%d", &q);

  int k;
  char p[27];

  for (int i = 0; i < q; i++) {
    scanf("%d%s", &k, p);

    for (int j = 0; j < 26; j++) {
      pp[j] = p[j] - 'a';
    }

    printf("%d\n", trie.find(s[k - 1]) + 1);
  }

  return 0;
}


Fixed submission:
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#define debug(x) cerr << #x << " = " << x << endl;

#define mod 1000000007              // 1e9+7(prime number)
#define INF 1000000000              // 1e9
#define LLINF 2000000000000000000LL // 2e18
#define SIZE 100010

int pp[26];

/* Trie */

struct Trie {
  int val;
  int val2;
  int depth;
  Trie *next[26];
  Trie *warp, *warp_back, *back;

  Trie() : val(0), val2(0), warp_back(this), back(this) {
    memset(next, 0, sizeof(next));
  }

  void insert(string &s, int i = 0) {
    val++; // 接頭辞のカウント
    depth = i;

    if (s[i]) {
      int al = s[i] - 'a';

      if (next[al] == NULL) {
        next[al] = new Trie;
        next[al]->warp = NULL;
        next[al]->back = this;
      }

      next[al]->insert(s, i + 1);
    } else {
      val2++; // 終端のカウント
    }
  }

  int find(string &s, int last_val = INF) {
    int ret = 0;

    if (val == 1)
      return 0;

    if (val == last_val) {
      warp_back = back->warp_back;
      back->warp_back->warp = this;
    }

    if (warp && warp != this) {
      return warp->find(s, val);
    }

    if (s[depth]) {
      int al = s[depth] - 'a';

      for (int j = 0; pp[j] != al; j++) {
        if (next[pp[j]])
          ret += next[pp[j]]->val;
      }

      if (next[al])
        return ret + val2 + next[al]->find(s, val);
      else
        return ret + val2;

    } else {
      return 0;
    }
  }
};

int main() {
  int n, q;
  char in[400001];
  string s[SIZE];
  Trie trie;

  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%s", in);
    s[i] = in;
    trie.insert(s[i]);
  }

  scanf("%d", &q);

  int k;
  char p[27];

  for (int i = 0; i < q; i++) {
    scanf("%d%s", &k, p);

    for (int j = 0; j < 26; j++) {
      pp[j] = p[j] - 'a';
    }

    printf("%d\n", trie.find(s[k - 1]) + 1);
  }

  return 0;
}