ロリハそのものな問題!!!
問題概要
長さ の文字列 が与えられ、 の連続する部分列が 個指定される。こうして作られる 個の文字列のうち、相異なるものは何通りあるか答えよ。
考えたこと
ロリハで頑張る
#include <iostream> #include <vector> #include <string> #include <algorithm> #include <set> using namespace std; struct RollingHash { const int base = 9973; const vector<int> mod = {999999937LL, 1000000007LL}; string S; vector<long long> hash[2], power[2]; // construct RollingHash(){} RollingHash(const string &cs) { init(cs); } void init(const string &cs) { S = cs; int n = (int)S.size(); for (int iter = 0; iter < 2; ++iter) { hash[iter].assign(n+1, 0); power[iter].assign(n+1, 1); for (int i = 0; i < n; ++i) { hash[iter][i+1] = (hash[iter][i] * base + S[i]) % mod[iter]; power[iter][i+1] = power[iter][i] * base % mod[iter]; } } } // get hash of S[left:right] inline long long get(int l, int r, int id = 0) const { long long res = hash[id][r] - hash[id][l] * power[id][r-l] % mod[id]; if (res < 0) res += mod[id]; return res; } // get lcp of S[a:] and S[b:] inline int getLCP(int a, int b) const { int len = min((int)S.size()-a, (int)S.size()-b); int low = -1, high = len + 1; while (high - low > 1) { int mid = (low + high) / 2; if (get(a, a+mid, 0) != get(b, b+mid, 0)) high = mid; else if (get(a, a+mid, 1) != get(b, b+mid, 1)) high = mid; else low = mid; } return low; } // get lcp of S[a:] and T[b:] inline int getLCP(const RollingHash &t, int a, int b) const { int len = min((int)S.size()-a, (int)S.size()-b); int low = -1, high = len + 1; while (high - low > 1) { int mid = (low + high) / 2; if (get(a, a+mid, 0) != t.get(b, b+mid, 0)) high = mid; else if (get(a, a+mid, 1) != t.get(b, b+mid, 1)) high = mid; else low = mid; } return low; } }; int main() { int N, M; cin >> N >> M; string S; cin >> S; RollingHash rh(S); set<pair<long long, long long> > res; int left = 0, right = 1; for (int q = 0; q < M; ++q) { string query; cin >> query; if (query == "R++") ++right; else if (query == "R--") --right; else if (query == "L++") ++left; else --left; pair<long long, long long> val(rh.get(left, right, 0), rh.get(left, right, 1)); res.insert(val); } cout << res.size() << endl; }