結果
問題 | No.430 文字列検索 |
ユーザー | shibh308 |
提出日時 | 2019-07-10 22:02:04 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 289 ms / 2,000 ms |
コード長 | 7,739 bytes |
コンパイル時間 | 2,098 ms |
コンパイル使用メモリ | 222,384 KB |
実行使用メモリ | 28,796 KB |
最終ジャッジ日時 | 2024-11-10 00:26:17 |
合計ジャッジ時間 | 3,671 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,816 KB |
testcase_01 | AC | 280 ms
28,796 KB |
testcase_02 | AC | 22 ms
6,820 KB |
testcase_03 | AC | 23 ms
6,816 KB |
testcase_04 | AC | 1 ms
6,816 KB |
testcase_05 | AC | 2 ms
6,824 KB |
testcase_06 | AC | 1 ms
6,816 KB |
testcase_07 | AC | 1 ms
6,816 KB |
testcase_08 | AC | 289 ms
28,376 KB |
testcase_09 | AC | 2 ms
6,816 KB |
testcase_10 | AC | 14 ms
6,816 KB |
testcase_11 | AC | 76 ms
9,596 KB |
testcase_12 | AC | 77 ms
9,724 KB |
testcase_13 | AC | 77 ms
9,852 KB |
testcase_14 | AC | 63 ms
8,188 KB |
testcase_15 | AC | 52 ms
7,292 KB |
testcase_16 | AC | 25 ms
6,816 KB |
testcase_17 | AC | 23 ms
6,820 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; using i64 = int64_t; const i64 MOD = (i64)1e9 + 7; const i64 INF = (i64)1e18 + 7; template <typename T = i64> struct Range{ struct iterator{ T value; const T step, last; const T& operator*(){return value;} iterator(T value, T step, T last) : value(step < static_cast<T>(0) ? max(last, value) : min(last, value)), step(step), last(last) { } iterator operator++(){value = step < static_cast<T>(0) ? max(value + step, last) : min(value + step, last); return *this;} bool operator!=(const iterator& x){return value != x.value;} }; const T start, last, step; Range(const T start, const T last, const T step = static_cast<T>(1)) : start(start), last(last), step(step) { } Range(const T last) : start(0), last(last), step(1) { } iterator begin(){return iterator(start, step, last);} iterator end(){return iterator(last, step, last);} }; template <typename F> struct FixPoint{ const F _f; FixPoint(F&& f) : _f(forward<F>(f)){} template<typename... Types> decltype(auto) operator()(Types&&... args) const{ return _f(*this, forward<Types>(args)...); } }; template <typename F> static decltype(auto) makeRec(F&& f){ return FixPoint<F>(forward<F>(f)); } template <typename T, T Value = T()> vector<T> makeVector(size_t x){ return vector<T>(x, T(Value)); } template <typename T, T Value = T(), typename... Types> auto makeVector(size_t x, Types... args){ return vector<decltype(makeVector<T, Value>(args...))>(x, makeVector<T, Value>(args...)); } template <typename T = i64> bool chmax(T& a, T b){ if(a < b){ a = b; return true; } return false; } template <typename T = i64> bool chmin(T& a, T b){ if(a > b){ a = b; return true; } return false; } #ifdef TEST #define dump(x) fprintf(stderr, "line =%4d, name =%7s , ", __LINE__, #x); cout << "value = " << x << endl; #define vecdump(x) fprintf(stderr, "line =%4d, name =%7s\n", __LINE__, #x); _dump_macro(x); #else #define vecdump(x) #define dump(x) #endif void _dump(int, string& x){ #ifdef TEST cout << x << endl; #endif } template <typename T> void _dump(bool, T& x){ #ifdef TEST cout << x << " "; #endif } template <typename T, typename U = typename T::iterator> void _dump(int, T& x){ #ifdef TEST for(auto& elm : x) _dump(0, elm); cout << endl; #endif } template <typename T> void _dump_macro(T& x){ _dump(0, x); } void _input(int, string& x){ cin >> x; } template <typename T> void _input(bool, T& x){ cin >> x; } template <typename T, typename U = typename T::iterator> void _input(int, T& x){ for(auto& elm : x) _input(0, elm); } template <typename T> void input_single(T& x){ _input(0, x); } auto input(){} template <typename T, typename... Types> void input(T& value, Types&&... args){ input_single(value); input(forward<Types>(args)...); }; void _pararell_input(size_t){} template <typename T, typename... Types> void _pararell_input(size_t index, T& value, Types&&... args){ input(value[index]); _pararell_input(index, forward<Types>(args)...); } template <typename... Types> void pararell_input(size_t count, Types&&... args){ for(const auto& i : Range<>(count)) _pararell_input(i, forward<Types>(args)...); } template <i64 mod = MOD> struct ModInt{ i64 p; ModInt() : p(0){} ModInt(i64 x){p = x >= 0 ? x % mod : x + (-x + mod - 1) / mod * mod;} ModInt& operator+=(const ModInt& y){p = p + *y - ((p + *y) >= mod ? mod : 0); return *this;} ModInt& operator-=(const ModInt& y){p = p - *y + (p - *y < 0 ? mod : 0); return *this;} ModInt& operator*=(const ModInt& y){p = (p * *y) % mod; return *this;} ModInt& operator%=(const ModInt& y){if(y)p %= *y; return *this;} ModInt operator+(const ModInt& y) const{ModInt x = *this; return x += y;} ModInt operator-(const ModInt& y) const{ModInt x = *this; return x -= y;} ModInt operator*(const ModInt& y) const{ModInt x = *this; return x *= y;} ModInt operator%(const ModInt& y) const{ModInt x = *this; return x %= y;} friend ostream& operator<<(ostream& stream, const ModInt<mod>& x){ stream << *x; return stream; } friend ostream& operator>>(ostream& stream, const ModInt<mod>& x){ stream >> *x; return stream; } ModInt& operator++(){p = (p + 1) % mod; return *this;} ModInt& operator--(){p = (p - 1 + mod) % mod; return *this;} bool operator==(const ModInt& y) const{return p == *y;} bool operator!=(const ModInt& y) const{return p != *y;} const i64& operator*() const{return p;} i64& operator*(){return p;} }; using mint = ModInt<MOD>; template <typename T = mint> function<T(T,i64)> mpow = [](T x, i64 y){ T z = x; T val = y & 1 ? x : T(1); while(z *= z, y >>= 1) if(y & 1) val *= z; return val; }; template <i64 mod1 = MOD, i64 mod2 = MOD + 2, i64 base = 10007, typename T = string> struct RollingHash{ using mint1 = ModInt<mod1>; using mint2 = ModInt<mod2>; using pair_type = pair<mint1, mint2>; int len; std::vector<pair_type> v; static std::vector<pair_type> power, inv; RollingHash(T s) : len(s.size()) { v.assign(1, make_pair(mint1(0), mint2(0))); for(int i = 0; i < len; ++i){ auto c = s[i]; v.emplace_back(v.back().first + power[i].first * c, v.back().second + power[i].second * c); if(static_cast<int>(power.size()) == i + 1){ power.emplace_back(power.back().first * base, power.back().second * base); inv.emplace_back(mpow<mint1>(power.back().first, mod1 - 2), mpow<mint2>(power.back().second, mod2 - 2)); } } }; pair_type get(int l = 0, int r = -1){ if(r == -1) r = len; assert(l <= r); assert(r <= len); auto l_cut = make_pair(v[r].first - v[l].first, v[r].second - v[l].second); return make_pair(l_cut.first * inv[l].first, l_cut.second * inv[r].second); } pair_type connect(pair_type l, pair_type r, int l_len){ return make_pair(l.first + power[l_len].first * r.first, l.second + power[l_len].second * r.second); } }; using RH = RollingHash<MOD, MOD + 2, 10007>; template<> vector<pair<ModInt<MOD>, ModInt<MOD + 2>>> RH::power = {make_pair(ModInt<MOD>(1), ModInt<MOD + 2>(1))}; template<> vector<pair<ModInt<MOD>, ModInt<MOD + 2>>> RH::inv = {make_pair(ModInt<MOD>(1), ModInt<MOD + 2>(1))}; i64 solve(i64 _count){ string s; int m = 0; input(s, m); vector<string> c(m); input(c); if(!static_cast<bool>(cin)) return MOD; #ifdef TEST cout << "Case: " << _count << endl; #endif vector<map<i64, int>> v(11); RH rh(s); for(int i = 0; i < rh.len; ++i) for(int j = 1; j <= 10 && i + j <= rh.len; ++j){ auto res = rh.get(i, i + j); ++v[j][(*res.first << 32) + *res.second]; } i64 ans = 0; for(auto& t : c){ RH rh2(t); auto res = rh2.get(); ans += v[rh2.len][(*res.first << 32) + *res.second]; } cout << ans << endl; return 0; } signed main(){ cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); int t = 0; while(solve(++t) != MOD); }