题目链接: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)

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define HASH 10007
#define MAXN 2007
struct StringMap{
int head[HASH],Next[MAXN],tot;
unsigned long long state[MAXN];
int f[MAXN];
void init(){
tot = ;
memset(head,-,sizeof(head));
}
int ins(unsigned long long val,int id)
{
int h = val%HASH;
for(int i = head[h];i != -;i = Next[i]){
if(val == state[i]){
int tmp = f[i];
f[i] = id;
return tmp;
}
}
f[tot] = id;
state[tot] = val;
Next[tot] = head[h];
head[h] = tot++;
return ;
}
}H;
char str[MAXN];
const int SEED = ;
unsigned long long p[MAXN];
unsigned long long s[MAXN];
int ans[MAXN][MAXN];
int main()
{
//freopen("in.txt","r",stdin);
p[] = ;
for(int i = ;i < MAXN;i++)
p[i] = p[i-]*SEED;
int T;
scanf("%d",&T);
while(T--){
scanf("%s",str);
int len = strlen(str);
s[] = ;
for(int i = ;i <= len;i++)
s[i] = s[i-]*SEED+str[i-];
memset(ans,,sizeof(ans));
for(int L = ;L <= len;L++){
H.init();
for(int i = ;i+L- <= len;i++){
int pos = H.ins(s[i+L-]-s[i-]*p[L],i);
ans[i][i+L-]++;
ans[pos][i+L-]--; //做标记
}
}
for(int i = len;i >= ;i--)
for(int j = i;j <= len;j++)
ans[i][j] += ans[i+][j] + ans[i][j-] - ans[i+][j-]; //递推出所有结果
int Q,l,r;
scanf("%d",&Q);
while(Q--){
scanf("%d%d",&l,&r);
printf("%d\n",ans[l][r]);
}
}
}

hdu 4622 Reincarnation 字符串hash 模板题的更多相关文章

  1. hdu-4080 Stammering Aliens 字符串hash 模板题

    http://acm.hdu.edu.cn/showproblem.php?pid=4080 求出现次数大于等于n的最长串. #include<iostream> #include< ...

  2. HDU 4622 Reincarnation Hash解法详解

    今天想学字符串hash是怎么弄的.就看到了这题模板题 http://acm.hdu.edu.cn/showproblem.php?pid=4622 刚开始当然不懂啦,然后就上网搜解法.很多都是什么后缀 ...

  3. hdu 4622 Reincarnation(后缀数组)

    hdu 4622 Reincarnation 题意:还是比较容易理解,给出一个字符串,最长2000,q个询问,每次询问[l,r]区间内有多少个不同的字串. (为了与论文解释统一,这里解题思路里sa数组 ...

  4. HDU 1880 字符串hash 入门题

    Problem Description 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔 ...

  5. HDU 4622 Reincarnation 后缀自动机 // BKDRHash(最优hash)

    Reincarnation Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) P ...

  6. HDU 2222(AC自动机模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题 ...

  7. HDU 5521.Meeting 最短路模板题

    Meeting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  8. HDU 1711 - Number Sequence - [KMP模板题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 Time Limit: 10000/5000 MS (Java/Others) Memory L ...

  9. HDU 4622 Reincarnation 后缀自动机

    模板来源:http://blog.csdn.net/zkfzkfzkfzkfzkfzkfzk/article/details/9669747 解法参考:http://blog.csdn.net/dyx ...

随机推荐

  1. TCP/IP协议原理与应用笔记18:构成子网和超网

    1. 引言: (1)类别IP编址(Classful IP)的缺陷 • 固定的3种IP网络规模      C类地址:少于255台主机的网络      B类地址:介于255~65535台主机的网络     ...

  2. Android(java)学习笔记94:关于广播接收者的注册和使用心得

    下面我们先看一部分代码,由代码进行进一步的深入: registerReceiver( new BroadcastReceiver() {//onReceive中代码的执行时间不要超过5s,androi ...

  3. 获取Spring-boot系统环境变量方法

    public static ConfigurableApplicationContext context = null; public static void main( String[] args ...

  4. Ehcache(2.9.x) - API Developer Guide, Transaction Support

    About Transaction Support Transactions are supported in versions of Ehcache 2.0 and higher. The 2.3. ...

  5. Linux 命令 - ls: 列出目录内容

    ls 命令很可能是用户最常使用的命令,通过 ls 命名可以查看目录内容,确定各种重要文件和目录的属性. 命令格式 ls [OPTION]... [FILE]... 命令参数 -a, --all 列出所 ...

  6. 关于easyui的一些小知识点(1)

    让layout布局自动适应浏览器宽度只需要加上fit="true"属性.

  7. JAVA-位运算符

    请解释&和&&.|和||的区别? 在逻辑运算中: · 与操作:与操作分为两种,一种是普通与,另外一种是短路与: |- 普通与(&):表示所有的判断条件都要执行,不管前面 ...

  8. 关闭“编辑窗体”后, 主窗体的DatagridView刷新数据的问题

    问题:在关闭一个窗体2后,要刷新窗体1内的datagridview的数据,直接窗体1.datagridview.datasource=dt 是没用的. 解决办法如下: 在主窗体里 创建编辑窗体时 加上 ...

  9. JavaScript动画附源码(一)

        JavaScript完成动画程序 1,效果图: 以上是纯CSS+JavaScript实现的.点击关闭按钮可以动态关闭这个方框.兼容IE/FF/Chrome.这样的效果如果用jquery实现起来 ...

  10. ASP.NET MVC 路由进阶(之一)

    1.  MVC框架下的WebForm页面. 我们在MVC项目下新建一个WebForm页面. 然后右键浏览,打开页面,如下图: 发现页面能够正常访问.ok,我们尝试改一下Global.asax.cs中的 ...