hash和字符串

/*
	此代码的主要思路是来自yxc大神的;不过这个代码全是我自己写的; 
*/ 

#include <iostream>
#include <string.h>
using namespace std;
typedef unsigned long long ull;
const int base=131,N = 1000010;
/*
	long long 是2^63 左右,而 unsigned long long 应该是 2^64 ;当一个数超过了2^64
	这样就会对其进行2^64  取余;
	base 最好的是131进制 或者13331进制 ,这是经过大量的实验总结出来的; 
*/
ull h[N],p[N];
/*
	h存的是前i位对应的hash;
	比如串 abcdefg
	h[1] 对应的是 a 的hash ;
	h[2] 对应的是 ab 的 hash;
	h[3] 对应的是abc 的 hash;
	 
*/
char s[N];
/*
这是我们的字符串 
*/

/*
这是求某子串的hash ;
这样我们就可以在o(1)的时间来访问每个子串的hash; 
*/
ull getSum(int l,int r)
{
	return h[r]-h[l-1]*p[r-l+1];
}

int main()
{
	h[0]=0;p[0]=1;
	scanf("%s",s+1);
	/*
		至于这个输入我也没看懂,反正就是从让其下标从1开始;(自己试出来的) 
	*/
	int len=strlen(s+1);
	for(int i=1;i<=len;i++)
	{
		h[i]=h[i-1]*base+s[i]-'a'+1;
		/*
			因为前面提到 
		*/
		p[i]=p[i-1]*base;//(分别对应的是131的i次幂) 
	}
	/*
		下面是对字串的测试;
		比如abcabcabc
		如果你输入m=3的话
		再输入l  r 
		l = 1,r = 3
		l = 4,r = 6
		l = 7,r = 9
		
		这三个的hash的值是一样的; 
	*/ 
	int m;
	int l,r;
	cin>>m;
	while(m--)
	{
		cin>>l>>r;
		cout<<getSum(l,r)<<endl;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值