Oulipo (hash table and string hash)

Oulipo

Idea: We need to find the hash value of b first, then calculate the prefix sum of a string, and then calculate each segment using the prefix sum to see which one satisfies the result, and the counter is incremented by one.
note

1. The string type needs to add std:: in front, otherwise an error will be reported (see below).
2. If you want to make the program faster, you can use the fast exponentiation algorithm (see below).
3. Cin accelerator can refer to (see below), std::ios::sync_with_stdio(false); is to untie cin and stdin or cout and stdout, cin.tie(0); and cout.tie(0); solution Tie the binding of the two.

Code

#include<bits/stdc++.h>
#define x 29999997
std::string a,b;
long long la,lb,num,hash[1000001],s,n,p=1,base=31,i,t;
using namespace std;
int main(){
    
    
	std::ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>a>>b;
	la=a.size();
	lb=b.size();
	n=lb;
	for(i=0;i<lb;i++)
		num=(b[i]+num*31%x)%x;
	while(n>0){
    
    
		if(n%2==1)
			p=p*base%x;
		n/=2;
		base=base*base%x;
	}
	for(i=1;i<=la;i++){
    
    
		hash[i]=(hash[i-1]*31%x+a[i-1])%x;
		if(i>=lb){
    
    
			s=((hash[i]-hash[i-lb]*p)%x+x)%x;
			if(s==num)
				t++;
		}
	}
	cout<<t;
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_52536621/article/details/113805875