結果

問題 No.430 文字列検索
ユーザー AC2KAC2K
提出日時 2023-03-29 13:24:43
言語 C++23
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 264 ms / 2,000 ms
コード長 3,921 bytes
コンパイル時間 2,676 ms
コンパイル使用メモリ 262,004 KB
実行使用メモリ 27,264 KB
最終ジャッジ日時 2024-11-10 01:05:51
合計ジャッジ時間 4,173 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
5,248 KB
testcase_01 AC 264 ms
27,264 KB
testcase_02 AC 11 ms
5,248 KB
testcase_03 AC 12 ms
5,248 KB
testcase_04 AC 2 ms
5,248 KB
testcase_05 AC 2 ms
5,248 KB
testcase_06 AC 1 ms
5,248 KB
testcase_07 AC 2 ms
5,248 KB
testcase_08 AC 241 ms
27,008 KB
testcase_09 AC 2 ms
5,248 KB
testcase_10 AC 15 ms
5,888 KB
testcase_11 AC 79 ms
8,192 KB
testcase_12 AC 80 ms
8,192 KB
testcase_13 AC 77 ms
8,192 KB
testcase_14 AC 67 ms
6,528 KB
testcase_15 AC 49 ms
5,760 KB
testcase_16 AC 16 ms
5,248 KB
testcase_17 AC 13 ms
5,248 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#line 2 "template.hpp"
#include<bits/stdc++.h>
using namespace std;
#define rep(i, N)  for(int i=0;i<(N);i++)
#define all(x) (x).begin(),(x).end()
#define popcount(x) __builtin_popcount(x)
using i128=__int128_t;
using ll = long long;
using ld = long double;
using graph = vector<vector<int>>;
using P = pair<int, int>;
constexpr int inf = 1e9;
constexpr ll infl = 1e18;
constexpr ld eps = 1e-6;
const long double pi = acos(-1);
constexpr uint64_t MOD = 1e9 + 7;
constexpr uint64_t MOD2 = 998244353;
constexpr int dx[] = { 1,0,-1,0 };
constexpr int dy[] = { 0,1,0,-1 };
template<class T>static constexpr inline void chmax(T&x,T y){if(x<y)x=y;}
template<class T>static constexpr inline void chmin(T&x,T y){if(x>y)x=y;}
#line 2 "math/mod_pow.hpp"
template <class T, class U = T>
U mod_pow(T base, T exp, T mod){
    T ans = 1;
    base %= mod;
    while (exp > 0) {
        if (exp & 1) {
            ans *= base;
            ans %= mod;
        }
        base *= base;
        base %= mod;
        exp >>= 1;
    }
    return ans;
}
///@brief mod pow(バイナリ法)
#line 3 "string/rolling_hash.hpp"
class RollingHash {
	using ull = uint_fast64_t;
    using i128 = __int128_t;
    using u128 = __uint128_t;
    // mod
	static constexpr ull msk30 = (1ul << 30) - 1;
	static constexpr ull msk61 = (1ul << 31) - 1;
	string str;
	vector<ull> hash, pow;

    static constexpr ull mod = (1uL << 61) - 1;
    static constexpr ull primitive_root = 37;
public:
	static const uint mapping_max = (uint)'Z' + 2;
	static ull base;
private:
	ull mul(const u128& a,const u128& b) const {
        u128 t = a * b;

		t = (t >> 61) + (t & mod);

		if (t >= mod) {
			t -= mod;
		}


		return t;
    }

    ull mapping(const char& c) const {
		return (ull)c;	//変更する?
	}


    static ull generate() {
		mt19937_64 engine(chrono::steady_clock::now().time_since_epoch().count());
		uniform_int_distribution<ull> rand(1uL, mod - 1);
		return rand(engine);
	}	
    static void generate_base() {
		if (base != 0){
			return;
		}
		ull r = mod - 1;

		while (gcd(r, mod - 1) != 1 || r <= mapping_max){
			r = generate();
		}
		base = mod_pow<__uint128_t>(primitive_root, r, mod);
	}
public:
	RollingHash() :str() {	}

	RollingHash(const string& str) :str(str) {
		generate_base();
		build();
	}

	void build() {
		hash.resize(str.size() + 1);
		pow.resize(str.size() + 1, 1);

		for (int i = 0; i < str.size(); i++) {
			hash[i + 1] = mul(hash[i], base) + mapping(str[i]);
			pow[i + 1] = mul(pow[i], base);
			if (hash[i + 1] >= mod) {
				hash[i + 1] -= mod;
			}
		}
	}
	ull range(int l, int r) const {
		ull res = mod + hash[r] - mul(hash[l], pow[r - l]);
		return res < mod ? res : res - mod;
	}
	ull get_all() const {
		return hash.back();
	}
	int size() const {return str.size();}

    static int lcp(const RollingHash &a, const RollingHash &b, const int &start_a, const int &start_b) {
        int ok = 0;
        int ng = min(a.size() - start_a, b.size() - start_b) + 1;
		while (abs(ok - ng) > 1){
			int md = (ok + ng) >> 1;
            if (a.range(start_a, start_a + md) == b.range(start_b, start_b + md)){
                ok = md;
            }
            else{
                ng = md;
            }
		}

		return ok;
    }
};
typename RollingHash::ull RollingHash::base;

///@brief Rollinghash(ローリングハッシュ)
#line 3 "main.cpp"

#pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
int main(){
    string s;
    int m;
    cin >> s >> m;
    RollingHash S(s);
    map<uint64_t, int> hash_count;
    rep(i, s.size()) {
        for (int length = 1; length <= 10 && i + length <= s.size(); length++) {
            int j = i + length;
            hash_count[S.range(i, j)]++;
        }
    }
    long long ans = 0;

    for (int i = 0; i < m; i++) {
        string c;
        cin >> c;
        ans += hash_count[RollingHash(c).get_all()];
    }
    cout << ans << '\n';
}
0