标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622
题意:给定一个长度不超过2000的字符串,之后有不超过1e5次的区间查询,输出每次查询区间中不同的子串个数?
做法1:字符串hash
一般的做法就是模拟每段子串的长度L(从1到 len),这样时间复杂度为O(n^2);但是里面并没有计算子串比较是否相等以及存储的时间,而这段时间就是将字符串看成是“数字”,这样存储和比较的时间均降为O(1)了;
下面讲讲模板;
1.如何将字符串看成一个“高精度的数字”,由于相同的子串不只是含有的字符个数的和字符类别要相同,同时还需要和数字一样分成在“什么位”上(如十位还是百位);下面的p[]就是这样一个表示在哪一位;同时s[i]表示的就是子串str[0...i-1],只不过表示成了数字的形式;这样之后就可以直接枚举长度L,并且将是否有重复的给“标记”下来;
注意:ans[pos][i+L-1] :表示的是只有子串起点在pos(其实之后的二维DP求和可以扩大到更大的区间),终点在i+L-1才需要-1;不是pos+L-1
2.将上面的标记累加起来,递推出二维的ans[][];即区间长度从小到大递推即可;
时间空间复杂度均为O(n^2)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 #define HASH 10007 6 #define MAXN 2007 7 struct StringMap{ 8 int head[HASH],Next[MAXN],tot; 9 unsigned long long state[MAXN]; 10 int f[MAXN]; 11 void init(){ 12 tot = 0; 13 memset(head,-1,sizeof(head)); 14 } 15 int ins(unsigned long long val,int id) 16 { 17 int h = val%HASH; 18 for(int i = head[h];i != -1;i = Next[i]){ 19 if(val == state[i]){ 20 int tmp = f[i]; 21 f[i] = id; 22 return tmp; 23 } 24 } 25 f[tot] = id; 26 state[tot] = val; 27 Next[tot] = head[h]; 28 head[h] = tot++; 29 return 0; 30 } 31 }H; 32 char str[MAXN]; 33 const int SEED = 13331; 34 unsigned long long p[MAXN]; 35 unsigned long long s[MAXN]; 36 int ans[MAXN][MAXN]; 37 int main() 38 { 39 //freopen("in.txt","r",stdin); 40 p[0] = 1; 41 for(int i = 1;i < MAXN;i++) 42 p[i] = p[i-1]*SEED; 43 int T; 44 scanf("%d",&T); 45 while(T--){ 46 scanf("%s",str); 47 int len = strlen(str); 48 s[0] = 0; 49 for(int i = 1;i <= len;i++) 50 s[i] = s[i-1]*SEED+str[i-1]; 51 memset(ans,0,sizeof(ans)); 52 for(int L = 1;L <= len;L++){ 53 H.init(); 54 for(int i = 1;i+L-1 <= len;i++){ 55 int pos = H.ins(s[i+L-1]-s[i-1]*p[L],i); 56 ans[i][i+L-1]++; 57 ans[pos][i+L-1]--; //做标记 58 } 59 } 60 for(int i = len;i >= 0;i--) 61 for(int j = i;j <= len;j++) 62 ans[i][j] += ans[i+1][j] + ans[i][j-1] - ans[i+1][j-1]; //递推出所有结果 63 int Q,l,r; 64 scanf("%d",&Q); 65 while(Q--){ 66 scanf("%d%d",&l,&r); 67 printf("%d\n",ans[l][r]); 68 } 69 } 70 }
hdu 4622 Reincarnation 字符串hash 模板题
标签:
原文地址:http://www.cnblogs.com/hxer/p/5670347.html