Hash_字串hash_二分_倍增_CH1809
阿新 • • 發佈:2018-11-09
思路分析: 字串hash配合二分或倍增均可, 下面先給出配合二分的AC程式碼, 然後給出配合倍增的AC程式碼:
//CH1809_匹配統計 #include <iostream> #include <cstdio> using namespace std; const int MAX = 2e5 + 5, P = 1331; unsigned long long ah[MAX], bh[MAX], ph[MAX]; char A[MAX], B[MAX]; int N, M, Q, ans[MAX];//ans[i]匹配長度為i的位置個數 int main(){ scanf("%d %d %d %s %s", &N, &M, &Q, A + 1, B + 1); ph[0] = 1; for(int i = 1; i < MAX; ++i) ph[i] = ph[i - 1] * P; for(int i = 1; i <= N; ++i) ah[i] = ah[i - 1] * P + (A[i] - 'a' + 1); for(int i = 1; i <= M; ++i) bh[i] = bh[i - 1] * P + (B[i] - 'a' + 1); for(int i = 1; i <= N; ++i){ int l = 0, r = min(N - i + 1, M), mid; while(mid = l + r + 1 >> 1, l < r) if(ah[i + mid - 1] - ah[i - 1] * ph[mid] == bh[mid]) l = mid; else r = mid - 1; ++ans[l]; } for(int i = 1, x; i <= Q; ++i) scanf("%d", &x), cout << ans[x] << endl; return 0; }
//CH1809_匹配統計 #include <iostream> #include <cstdio> using namespace std; const int MAX = 2e5 + 5, P = 1331; unsigned long long ah[MAX], bh[MAX], ph[MAX]; char A[MAX], B[MAX]; int N, M, Q, ans[MAX];//ans[i]匹配長度為i的位置個數 int main(){ scanf("%d %d %d %s %s", &N, &M, &Q, A + 1, B + 1); ph[0] = 1; for(int i = 1; i < MAX; ++i) ph[i] = ph[i - 1] * P; for(int i = 1; i <= N; ++i) ah[i] = ah[i - 1] * P + (A[i] - 'a' + 1); for(int i = 1; i <= M; ++i) bh[i] = bh[i - 1] * P + (B[i] - 'a' + 1); for(int i = 1; i <= N; ++i){ int begin = 0, len = 2, t; while(t = begin + len - 1, len >= 2) if(t <= min(N - i + 1, M) && ah[i + t - 1] - ah[i - 1] * ph[t] == bh[t]) begin = t, len <<= 1; else len >>= 1; ++ans[begin]; } for(int i = 1, x; i <= Q; ++i) scanf("%d", &x), cout << ans[x] << endl; return 0; }