Algorithm-Library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub UScuber/Algorithm-Library

:heavy_check_mark: test/aoj/ALDS1/ALDS1_14_B.test.cpp

Depends on

Code

#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/problems/ALDS1_14_B"

#include "../../../template/template.hpp"

#include "../../../string/rolling-hash.hpp"

RollingHash<10000> roliha;
int main(){
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  string s,t;
  cin >> s >> t;
  const auto sh = roliha.gen(s);
  const auto th = roliha.gen(t);
  for(int i = 0; i + t.size() <= s.size(); i++){
    if(sh.query(i, i+t.size()) == th.query(0, t.size())){
      cout << i << "\n";
    }
  }
}
#line 1 "test/aoj/ALDS1/ALDS1_14_B.test.cpp"
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/problems/ALDS1_14_B"

#line 1 "template/template.hpp"
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <tuple>
#include <cstdint>
#include <cstdio>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <deque>
#include <bitset>
#include <cctype>
#include <climits>
#include <functional>
#include <cassert>
#include <numeric>
#include <cstring>
#define rep(i, n) for(int i = 0; i < (n); i++)
#define per(i, n) for(int i = (n) - 1; i >= 0; i--)
using ll = long long;
#define vi vector<int>
#define vvi vector<vi>
#define vl vector<ll>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
constexpr int mod = 1000000007;
using namespace std;
template<class T, class U>
bool chmax(T &a, const U &b){ return a < b ? (a = b, 1) : 0; }
template<class T, class U>
bool chmin(T &a, const U &b){ return a > b ? (a = b, 1) : 0; }
#line 4 "test/aoj/ALDS1/ALDS1_14_B.test.cpp"

#line 1 "string/rolling-hash.hpp"
#include <chrono>
#include <random>
using ull = unsigned long long;

template <class T, int max_len>
struct Hash {
  static constexpr ull m = (1ULL << 61) - 1;
  const ull base;
  vector<ull> h;
  const T data;
  Hash(const T &d, const ull base, const ull power[]) : data(d), base(base), power(power){}
  inline ull query(int l, int r) const{
    assert(max_len >= r - l);
    assert(0 <= l && l <= r && r <= h.size());
    return add(h[r], m - mul(h[l], power[r - l]));
  }
  void combine(const Hash<T, max_len> &a){
    const int len = h.size();
    h.insert(h.end(), a.h.begin()+1, a.h.end());
    const int tot_len = h.size();
    ull val = h[len - 1];
    for(int i = len; i < tot_len; i++){
      val = mul(val, base);
      h[i] = add(val, h[i]);
    }
  }
  inline int size() const noexcept{ return (int)h.size()-1; }
  private:
  const ull *power;
  inline ull add(ull a, const ull b) const noexcept{
    if((a += b) >= m) a -= m;
    return a;
  }
  inline ull mul(const ull a, const ull b) const noexcept{
    const __uint128_t c = (__uint128_t)a * b;
    return add(c >> 61, c & m);
  }
  inline ull fma(const ull a, const ull b, const ull c) const noexcept{
    const __uint128_t d = (__uint128_t)a * b + c;
    return add(d >> 61, d & m);
  }
};
template <int max_len>
struct RollingHash {
  static constexpr ull m = (1ULL << 61) - 1;
  const ull base;
  RollingHash() : base(rnd()){
    power[0] = 1;
    for(int i = 0; i < max_len; i++){
      power[i + 1] = mul(power[i], base);
    }
  }
  Hash<string, max_len> gen(const string &s) const{
    const int len = s.size();
    Hash<string, max_len> hash(s, base, power);
    hash.h.resize(len + 1);
    for(int i = 0; i < len; i++){
      hash.h[i+1] = fma(hash.h[i], base, s[i]);
    }
    return hash;
  }
  template <class T>
  Hash<vector<T>, max_len> gen(const vector<T> &s) const{
    const int len = s.size();
    Hash<vector<T>, max_len> hash(s, base, power);
    hash.h.resize(len + 1);
    for(int i = 0; i < len; i++){
      hash.h[i+1] = fma(hash.h[i], base, s[i]);
    }
    return hash;
  }
  ull combine(const ull h1, const ull h2, const ull h2_len) const{
    assert(max_len >= h2_len);
    return fma(h1, power[h2_len], h2);
  }
  template <class T>
  ull combine(const Hash<T,max_len> &a, const int l1, const int r1,
              const Hash<T,max_len> &b, const int l2, const int r2) const{
    assert(max_len >= r2 - l2);
    return fma(a.query(l1, r1), power[r2-l2], b.query(l2, r2));
  }
  template <class T>
  int lcp(const Hash<T,max_len> &a, const int l1, const int r1,
          const Hash<T,max_len> &b, const int l2, const int r2) const{
    assert(0 <= l1 && l1 <= r1 && r1 <= a.size());
    assert(0 <= l2 && l2 <= r2 && r2 <= b.size());
    const int len = min(r1-l1, r2-l2);
    int left = 0, right = len + 1;
    while(left + 1 < right){
      const int mid = (left + right) / 2;
      if(a.query(l1, l1+mid) == b.query(l2, l2+mid)) left = mid;
      else right = mid;
    }
    return left;
  }
  template <class T>
  int strcmp(const Hash<T,max_len> &a, const int l1, const int r1
            ,const Hash<T,max_len> &b, const int l2, const int r2) const{
    assert(0 <= l1 && l1 <= r1 && r1 <= a.size());
    assert(0 <= l2 && l2 <= r2 && r2 <= b.size());
    const int pos = lcp(a, l1, r1, b, l2, r2);
    if(pos < min(r1-l1, r2-l2)) return a.data[l1+pos] < b.data[l2+pos] ? 1 : -1;
    if(r1-l1 == r2-l2) return 0;
    return r1-l1 < r2-l2 ? 1 : -1;
  }
  private:
  ull power[max_len + 1];
  ull rnd() const{
    mt19937_64 mt(chrono::steady_clock::now().time_since_epoch().count());
    uniform_int_distribution<ull> rand(2, m-1);
    return rand(mt);
  }
  inline ull add(ull a, const ull b) const noexcept{
    if((a += b) >= m) a -= m;
    return a;
  }
  inline ull mul(const ull a, const ull b) const noexcept{
    const __uint128_t c = (__uint128_t)a * b;
    return add(c >> 61, c & m);
  }
  inline ull fma(const ull a, const ull b, const ull c) const noexcept{
    const __uint128_t d = (__uint128_t)a * b + c;
    return add(d >> 61, d & m);
  }
};
#line 6 "test/aoj/ALDS1/ALDS1_14_B.test.cpp"

RollingHash<10000> roliha;
int main(){
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  string s,t;
  cin >> s >> t;
  const auto sh = roliha.gen(s);
  const auto th = roliha.gen(t);
  for(int i = 0; i + t.size() <= s.size(); i++){
    if(sh.query(i, i+t.size()) == th.query(0, t.size())){
      cout << i << "\n";
    }
  }
}
Back to top page