Problem p02816 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <climits>
#include <complex>
#include <cstring>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

#define rep(i, m, n) for (int i = int(m); i < int(n); i++)
#define all(c) begin(c), end(c)

template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}

template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

typedef long long int ll;
using ll = long long int;
using ull = long long unsigned int;
// using Int = long long int;
using Int = int;
using namespace std;
#define INF (1 << 30) - 1
#define INFl (ll)5e15
#define DEBUG 0
#define dump(x) cerr << #x << " = " << (x) << endl
#define MOD 1000000007

// edit
template <unsigned mod> struct RollingHash {
  vector<unsigned> hashed, power;

  inline unsigned mul(unsigned a, unsigned b) const {
    unsigned long long x = (unsigned long long)a * b;
    unsigned xh = (unsigned)(x >> 32), xl = (unsigned)x, d, m;
    asm("divl %4; \n\t" : "=a"(d), "=d"(m) : "d"(xh), "a"(xl), "r"(mod));
    return m;
  }

  RollingHash(const string &s, unsigned base = 107) {
    int sz = (int)s.size();
    hashed.assign(sz + 1, 0);
    power.assign(sz + 1, 0);
    power[0] = 1;
    for (int i = 0; i < sz; i++) {
      power[i + 1] = mul(power[i], base);
      hashed[i + 1] = mul(hashed[i], base) + s[i];
      if (hashed[i + 1] >= mod)
        hashed[i + 1] -= mod;
    }
  }

  unsigned get(int l, int r) const {
    unsigned ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
    if (ret >= mod)
      ret -= mod;
    return ret;
  }

  unsigned connect(unsigned h1, int h2, int h2len) const {
    unsigned ret = mul(h1, power[h2len]) + h2;
    if (ret >= mod)
      ret -= mod;
    return ret;
  }

  int LCP(const RollingHash<mod> &b, int l1, int r1, int l2, int r2) {
    int len = min(r1 - l1, r2 - l2);
    int low = -1, high = len + 1;
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (get(l1, l1 + mid) == b.get(l2, l2 + mid))
        low = mid;
      else
        high = mid;
    }
    return (low);
  }
};

using RH7 = RollingHash<1000000007>;
using RH9 = RollingHash<1000000009>;

class Solve {
public:
  Int N;
  vector<Int> A, B;

  void input() {
    cin >> N;
    A.resize(N);
    B.resize(N);

    for (int i = 0; i < N; ++i)
      cin >> A[i];
    for (int i = 0; i < N; ++i)
      cin >> B[i];
  }

  void input2() {
    N = 200000;
    A.resize(N);
    B.resize(N);
    for (int i = 0; i < N; ++i)
      A[i] = 81002285;
    for (int i = 0; i < N; ++i)
      B[i] = 81002285;
  }

  void solve() {

    using RH = pair<RH7, RH9>;
    //        vector<RH> aRH(32);
    //        vector<RH> raRH(32); //aRHの反転したもの
    //        vector<RH> bRH(32);
    vector<RH> aRH;
    vector<RH> raRH; // aRHの反転したもの
    vector<RH> bRH;
    double sum_t = 0.0;
    clock_t start_t = clock();
    for (int i = 0; i < 30; ++i) {
      string a, ra, b;
      for (int j = 0; j < N; ++j) {
        if (A[j] >> i & 1) {
          a += '1';
        } else {
          a += '0';
        }
        ra += a.back() ^ 1;
        if (B[j] >> i & 1) {
          b += '1';
        } else {
          b += '0';
        }
      }
      for (int j = 0; j < N; ++j) {
        if (A[j] >> i & 1) {
          a += '1';
        } else {
          a += '0';
        }
        ra += a.back() ^ 1;
      }
      //            a += a;
      //            ra += ra;

      //            aRH[i] = make_pair(RH7(a), RH9(a));
      //            raRH[i] = make_pair(RH7(ra), RH9(ra));
      //            bRH[i] = make_pair(RH7(b), RH9(b));
      aRH.push_back(make_pair(move(RH7(a)), move(RH9(a))));
      //            raRH.push_back(make_pair(RH7(ra), RH9(ra)));
      //            bRH.push_back(make_pair(RH7(b), RH9(b)));
      raRH.push_back(make_pair(move(RH7(ra)), move(RH9(ra))));
      bRH.push_back(make_pair(move(RH7(b)), move(RH9(b))));
    }

    clock_t end_t = clock();
    sum_t += 1.0 * (end_t - start_t) / CLOCKS_PER_SEC;

    vector<pair<Int, Int>> ans;

    for (int k = 0; k < N; ++k) {
      bool ok = true;
      for (int i = 0; i < 30; ++i) {
        auto bf = bRH[i].first.get(0, N);
        auto bs = bRH[i].second.get(0, N);

        bool flag1 = aRH[i].first.get(k, k + N) == bf &&
                     aRH[i].second.get(k, k + N) == bs;
        bool flag2 = raRH[i].first.get(k, k + N) == bf &&
                     raRH[i].second.get(k, k + N) == bs;
        if (!flag1 && !flag2) {
          ok = false;
          break;
        }
      }

      if (ok) {
        Int x = A[k] ^ B[0];
        ans.emplace_back(k, x);
      }
    }

    sort(all(ans));
    for (auto e : ans) {
      //            cout << e.first << " " << e.second << endl;
      printf("%d %d\n", e.first, e.second);
    }

    //        double uku = sum_t;
    //        cout << uku << endl;
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);

  //    Solve().solve();
  Solve solve;
  solve.input();
  solve.solve();

  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <climits>
#include <complex>
#include <cstring>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

#define rep(i, m, n) for (int i = int(m); i < int(n); i++)
#define all(c) begin(c), end(c)

template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}

template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

typedef long long int ll;
using ll = long long int;
using ull = long long unsigned int;
// using Int = long long int;
using Int = int;
using namespace std;
#define INF (1 << 30) - 1
#define INFl (ll)5e15
#define DEBUG 0
#define dump(x) cerr << #x << " = " << (x) << endl
#define MOD 1000000007

// edit
template <unsigned mod> struct RollingHash {
  vector<unsigned> hashed, power;

  inline unsigned mul(unsigned a, unsigned b) const {
    unsigned long long x = (unsigned long long)a * b;
    unsigned xh = (unsigned)(x >> 32), xl = (unsigned)x, d, m;
    asm("divl %4; \n\t" : "=a"(d), "=d"(m) : "d"(xh), "a"(xl), "r"(mod));
    return m;
  }

  RollingHash(const string &s, unsigned base = 107) {
    int sz = (int)s.size();
    hashed.assign(sz + 1, 0);
    power.assign(sz + 1, 0);
    power[0] = 1;
    for (int i = 0; i < sz; i++) {
      power[i + 1] = mul(power[i], base);
      hashed[i + 1] = mul(hashed[i], base) + s[i];
      if (hashed[i + 1] >= mod)
        hashed[i + 1] -= mod;
    }
  }

  unsigned get(int l, int r) const {
    unsigned ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
    if (ret >= mod)
      ret -= mod;
    return ret;
  }

  unsigned connect(unsigned h1, int h2, int h2len) const {
    unsigned ret = mul(h1, power[h2len]) + h2;
    if (ret >= mod)
      ret -= mod;
    return ret;
  }

  int LCP(const RollingHash<mod> &b, int l1, int r1, int l2, int r2) {
    int len = min(r1 - l1, r2 - l2);
    int low = -1, high = len + 1;
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (get(l1, l1 + mid) == b.get(l2, l2 + mid))
        low = mid;
      else
        high = mid;
    }
    return (low);
  }
};

using RH7 = RollingHash<1000000007>;
using RH9 = RollingHash<1000000009>;

class Solve {
public:
  Int N;
  vector<Int> A, B;

  void input() {
    cin >> N;
    A.resize(N);
    B.resize(N);

    for (int i = 0; i < N; ++i)
      cin >> A[i];
    for (int i = 0; i < N; ++i)
      cin >> B[i];
  }

  void input2() {
    N = 200000;
    A.resize(N);
    B.resize(N);
    for (int i = 0; i < N; ++i)
      A[i] = 81002285;
    for (int i = 0; i < N; ++i)
      B[i] = 81002285;
  }

  void solve() {

    using RH = pair<RH7, RH9>;
    //        vector<RH> aRH(32);
    //        vector<RH> raRH(32); //aRHの反転したもの
    //        vector<RH> bRH(32);
    vector<RH> aRH;
    vector<RH> raRH; // aRHの反転したもの
    vector<RH> bRH;
    double sum_t = 0.0;
    clock_t start_t = clock();
    for (int i = 0; i < 30; ++i) {
      string a, ra, b;
      for (int j = 0; j < N; ++j) {
        if (A[j] >> i & 1) {
          a += '1';
        } else {
          a += '0';
        }
        ra += a.back() ^ 1;
        if (B[j] >> i & 1) {
          b += '1';
        } else {
          b += '0';
        }
      }
      for (int j = 0; j < N; ++j) {
        if (A[j] >> i & 1) {
          a += '1';
        } else {
          a += '0';
        }
        ra += a.back() ^ 1;
      }
      //            a += a;
      //            ra += ra;

      //            aRH[i] = make_pair(RH7(a), RH9(a));
      //            raRH[i] = make_pair(RH7(ra), RH9(ra));
      //            bRH[i] = make_pair(RH7(b), RH9(b));
      aRH.push_back(make_pair(move(RH7(a)), move(RH9(a))));
      //            raRH.push_back(make_pair(RH7(ra), RH9(ra)));
      //            bRH.push_back(make_pair(RH7(b), RH9(b)));
      raRH.push_back(make_pair(move(RH7(ra)), move(RH9(ra))));
      bRH.push_back(make_pair(move(RH7(b)), move(RH9(b))));
    }

    clock_t end_t = clock();
    sum_t += 1.0 * (end_t - start_t) / CLOCKS_PER_SEC;

    vector<pair<Int, Int>> ans;

    for (int k = 0; k < N; ++k) {
      bool ok = true;
      for (int i = 0; i < 30; ++i) {
        auto bf = bRH[i].first.get(0, N);
        //                auto bs = bRH[i].second.get(0, N);

        //                bool flag1 = aRH[i].first.get(k, k + N) == bf &&
        //                             aRH[i].second.get(k, k + N) == bs;
        //                bool flag2 = raRH[i].first.get(k, k + N) == bf &&
        //                             raRH[i].second.get(k, k + N) == bs;

        bool flag1 = aRH[i].first.get(k, k + N) == bf;
        bool flag2 = raRH[i].first.get(k, k + N) == bf;
        if (!flag1 && !flag2) {
          ok = false;
          break;
        }
      }

      if (ok) {
        Int x = A[k] ^ B[0];
        ans.emplace_back(k, x);
      }
    }

    sort(all(ans));
    for (auto e : ans) {
      //            cout << e.first << " " << e.second << endl;
      printf("%d %d\n", e.first, e.second);
    }

    //        double uku = sum_t;
    //        cout << uku << endl;
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);

  //    Solve().solve();
  Solve solve;
  solve.input();
  solve.solve();

  return 0;
}