Hash_字符串hash_二分_倍增_CH1809

版权声明:本文为博主原创作品, 转载请注明出处! https://blog.csdn.net/solider98/article/details/83862108

点此打开题目页面

思路分析: 字符串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;
} 

猜你喜欢

转载自blog.csdn.net/solider98/article/details/83862108