返回全部题目 
题目描述 
小 F 有一个字符串s s s t t t t t t s s s s s s t t t t t t I'll write one for you。
输入 
小写字母组成的子串s s s s s s [ 1 , 1 e 6 ] [1,1e6] [ 1 , 1 e 6 ] 
输出 
存在则输出t t t I'll write one for you
样例输入 
样例输出 
比如我现在有一串字符串 fixprefixixffix,因为都是小写,我们可以将其转换为0 ∼ 25 0\sim25 0 ∼ 2 5 5,8,23,15,17,4,5,8,23,8,23,5,5,8,23。
勘误:尽量不要用0 0 0 1 ∼ 26 1\sim26 1 ∼ 2 6 
首先复习一下,如果我要多次查询连续几项的和,如第1 ∼ 3 1\sim3 1 ∼ 3 7 ∼ 9 7\sim9 7 ∼ 9 
聪明的你知道,先预处理前缀和,得到 5,13,36,51,68,72,77,85,108,116,139,144,149,157,180,那么 sum[3]-sum[0]=36, sum[9]-sum[6]=36 即是结果,前缀和处理可以大大降低时间复杂度。
如果我问,哪些连续三项的和等于 36,你一定也能很快得出结果,是1 ∼ 3 ,   7 ∼ 9 ,   10 ∼ 12 ,   13 ∼ 15 1\sim3,~7\sim9,~10\sim12,~13\sim15 1 ∼ 3 ,   7 ∼ 9 ,   1 0 ∼ 1 2 ,   1 3 ∼ 1 5 
我们发现,这里面有些恰好是 fix,但有些不是,比如 ixf,利用前缀和搜索是不可行的,因为就算这几项的和相同,字母也不一定相同。
有什么办法解决呢?
就拿阿拉伯数字举例,我要知道19082 19082 1 9 0 8 2 19 19 1 9 1 + 9 = 8 + 2 1+9=8+2 1 + 9 = 8 + 2 19 = 82 19=82 1 9 = 8 2 19 = 1 × 10 + 9 ≠ 8 × 10 + 2 = 82 19=1\times10+9\neq8\times10+2=82 1 9 = 1 × 1 0 + 9  = 8 × 1 0 + 2 = 8 2 19 = 1 × 10 + 9 = 1 × 10 + 9 = 19 19=1\times10+9=1\times10+9=19 1 9 = 1 × 1 0 + 9 = 1 × 1 0 + 9 = 1 9 
这启发我们,可以对高位乘上一个数字,比如29 29 2 9 将这一串数看做29 \bold{29} 2 9  ,那么比较就轻而易举了。(一般选用131 131 1 3 1 13331 13331 1 3 3 3 1 
具体地说,第1 ∼ 3 1\sim3 1 ∼ 3 fix 字符串的 新概念和  为5 × 2 9 2 + 8 × 29 + 23 = 4460 5\times29^2+8\times29+23=4460 5 × 2 9 2 + 8 × 2 9 + 2 3 = 4 4 6 0 10 ∼ 12 10\sim12 1 0 ∼ 1 2 ixf 字符串的 新概念和 8 × 2 9 2 + 23 × 29 + 5 = 7400 8\times29^2+23\times29+5=7400 8 × 2 9 2 + 2 3 × 2 9 + 5 = 7 4 0 0 
这就是核心思想,可以找一些字符串感受感受∼ \sim ∼ 
当然,按照前缀和的思想,我们也需要先预处理 新概念前缀和  ,再进行查询操作。
预处理的时候,我们对第i i i 2 9 i 29^i 2 9 i 5 × 29 ,   8 × 2 9 2 ,   23 × 2 9 3 ,   15 × 2 9 4 ,   17 × 2 9 5 … 5\times29,~8\times29^2,~23\times29^3,~15\times29^4,~17\times29^5\dots 5 × 2 9 ,   8 × 2 9 2 ,   2 3 × 2 9 3 ,   1 5 × 2 9 4 ,   1 7 × 2 9 5 … 145 , 6728 , 560947 , 10609215 , 348689533 145,6728,560947,10609215,348689533 1 4 5 , 6 7 2 8 , 5 6 0 9 4 7 , 1 0 6 0 9 2 1 5 , 3 4 8 6 8 9 5 3 3 145 , 6873 , 567820 , 11177035 , 359866568 145,6873,567820,11177035,359866568 1 4 5 , 6 8 7 3 , 5 6 7 8 2 0 , 1 1 1 7 7 0 3 5 , 3 5 9 8 6 6 5 6 8 
如果我要找8 , 23 , 15 8,23,15 8 , 2 3 , 1 5 新概念和  ,是8 × 29 + 23 × 2 9 2 + 15 × 2 9 3 = 385410 8\times29+23\times29^2+15\times29^3=385410 8 × 2 9 + 2 3 × 2 9 2 + 1 5 × 2 9 3 = 3 8 5 4 1 0 1 ∼ 3 1\sim3 1 ∼ 3 567820 − 0 ≠ 385410 567820-0\ne385410 5 6 7 8 2 0 − 0  = 3 8 5 4 1 0 2 ∼ 4 2\sim4 2 ∼ 4 ( 11177035 − 145 ) / 29 = 385410 (11177035-145)/29=385410 ( 1 1 1 7 7 0 3 5 − 1 4 5 ) / 2 9 = 3 8 5 4 1 0 3 ∼ 5 3\sim5 3 ∼ 5 ( 359866568 − 6873 ) / 2 9 2 = 427895 ≠ 385410 (359866568-6873)/29^2=427895\ne385410 ( 3 5 9 8 6 6 5 6 8 − 6 8 7 3 ) / 2 9 2 = 4 2 7 8 9 5  = 3 8 5 4 1 0 2 9 2 29^2 2 9 2 
就这样在Θ ( n ) \Theta(n) Θ ( n ) 
下面上模板:
定义变量:
1 2 const  int  H = 29 ; unsigned  long  long  sum[M], p[M];
预处理:
1 2 3 4 5 6 7 void  init ()  	p[0 ] = 1 ; 	for  (int  j = 1 ; j <= m; j++) { 		p[j] = p[j - 1 ] * H;  		sum[j] = sum[j - 1 ] * H + (s[j] - 'a' );  	} } 
查询:
1 2 3 4 5 6 7 8 int  get (int  i, int  j)  	return  sum[j] - sum[i - 1 ] * p[j - i + 1 ]; } int  main ()      if  (get (a) == get (l,r)) {              } } 
好啦,现在你可以尝试完成本文开头那道题目了∼ \sim ∼ 
AC~code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #include  <iostream>  #define  ull unsigned long long #define  Code int main() { int T = 1; #define  Codes int main() { int T; scanf("%d\n" , &T);  #define  by while (T--) eachT(); #define  HTLDL return 0; #define  HappyNewYear } const  int  M = 1e6  + 7 ;const  int  H = 29 ;ull sum[M], p[M]; std::string s; void  init (int  m)  	p[0 ] = 1 ; 	for  (int  j = 1 ; j <= m; j++) { 		p[j] = p[j - 1 ] * H; 		sum[j] = sum[j - 1 ] * H + s[j] - 'a' ; 	} } ull get (int  i, int  j)   {	return  sum[j] - sum[i - 1 ] * p[j - i + 1 ]; } void  eachT ()  	std::cin >> s; 	int  m = s.size (); 	s = " "  + s; 	init (m); 	for  (int  len = m - 1 ; len >= 1 ; --len) { 		ull h1 = get (1 , len), h2 = get (m - len + 1 , m); 		if  (h1 != h2) continue ; 		for  (int  i = 2 ; i <= m - len; ++i) { 			h2 = get (i, i + len - 1 ); 			if  (h1 == h2) { 				for  (int  j = 1 ; j <= len; ++j) 					std::cout << s[j]; 				return ; 			} 		} 	} 	std::cout << "I'll write one for you" ; } Code by HTLDL HappyNewYear 
最后附赠一个练习题:
题目描述 
就像 小 F 有幸运数字一样,太阳也有喜欢的字符串A A A A A A A A A 小 F 喜欢赞美太阳,同时她还有n n n B 1 B_1 B 1  B 2 B_2 B 2  B 3 B_3 B 3  A A A 
输入 
第一行为字符串A A A ⩽ 1 e 6 \leqslant1e6 ⩽ 1 e 6 n ⩽ 1000 n\leqslant1000 n ⩽ 1 0 0 0 n n n B 1 ∼ B n B_1\sim B_n B 1  ∼ B n  1 e 6 1e6 1 e 6 1 e 7 1e7 1 e 7 
输出 
输出n n n A A A 
样例输入 
1 2 3 4 abab 2 abababab ababcbaba 
样例输出 
作者在一小时前刚初步了解了哈希,并写下了这篇笔记,如有错误恳请各位指出。
应该比较容易理解吧、、、