也是需要查看,然后修改,rolling hash, recursive hash, polynomial hash, double hash.如果一次不够,那就2次。需要在准备一个线段树,基本的线段树容易些,带lazy标记的区间修改的线段树不是很好写。hash seed key根据需要选择, 我看别人写的,可以写成一个随机数,每次随机选择一个素数作为种子,这样好像好一些。
1 #include<bits/stdc++.h> 2 #define pb push_back 3 #define FOR(i, n) for (int i = 0; i < (int)n; ++i) 4 #define dbg(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl 5 typedef long long ll; 6 using namespace std; 7 typedef pair<int, int> pii; 8 const int maxn = 1e6 + 10; 9 const int mod1 = 1e9 + 7; 10 const int mod2 = 1e9 + 9; 11 const int arg1 = 841; 12 const int arg2 = 151; 13 int n, k; 14 string str; 15 pii H[maxn]; 16 map<pii, int> has[maxn]; 17 map<pii, int> g; 18 int pw1, pw2; 19 bool check(map<pii, int> & m) { 20 for (auto it = m.begin(); it != m.end(); it++) { 21 if(it->second > 1) return 0; 22 else if(g.find(it->first) == g.end()) return false; 23 } 24 return 1; 25 } 26 void solve() { 27 cin >> n >> k; 28 cin >> str; 29 pw1 = pw2 = 1; 30 for (int i = 0; i < k - 1; i++) { 31 pw1 = ll(pw1) * arg1 % mod1; 32 pw2 = ll(pw2) * arg2 % mod2; 33 } 34 pii h = pii(0, 0); 35 for (int i = 0; i < k; i++) { 36 h.first = (ll(h.first) * arg1 + ll(str[i] - 'a' + 1)) % mod1; 37 h.second = (ll(h.second) * arg2 + ll(str[i] - 'a' + 1)) % mod2; 38 } 39 H[0] = h; 40 has[0][h]++; 41 for (int i = 1; i < n * k; i++) { 42 h.first = (ll(h.first) - ll(str[i - 1] - 'a' + 1) * pw1 % mod1 + mod1) % mod1; 43 h.second = (ll(h.second) - ll(str[i - 1] - 'a' + 1) * pw2 % mod2 + mod2) % mod2; 44 int ni = (i + k - 1) % (n * k); 45 h.first = (ll(h.first) * arg1 + ll(str[ni] - 'a' + 1)) % mod1; 46 h.second = (ll(h.second) * arg2 + ll(str[ni] - 'a' + 1)) % mod2; 47 has[i % k][h]++; 48 H[i] = h; 49 } 50 int m; cin >> m; 51 string cur; 52 for (int j = 1; j <= m; j++) { 53 cin >> cur; 54 pii h = pii(0, 0); 55 for (int i = 0; i < k; i++) { 56 h.first = (ll(h.first) * arg1 + ll(cur[i] - 'a' + 1)) % mod1; 57 h.second = (ll(h.second) * arg2 + ll(cur[i] - 'a' + 1)) % mod2; 58 g[h] = j; 59 } 60 } 61 for (int j = 0; j < k; j++) if(check(has[j])) { 62 cout << "YES" << endl; 63 bool f = 0; 64 for (int i = j; i < n * k; i += k) { 65 if(f) cout << " "; 66 cout << g[H[i]]; f = 1; 67 } 68 cout << endl; 69 return; 70 } 71 cout << "NO" << endl; 72 } 73 int main() { 74 //freopen("test.in", "r", stdin); 75 //freopen("test.out", "w", stdout); 76 solve(); 77 return 0; 78 }