D. Match & Catch

能够用各种方法做。字符串hash。后缀数组,dp。拓展kmp,字典树。。

字符串hash(模板)

http://blog.csdn.net/gdujian0119/article/details/6777239

BKDR Hash Function  :
// BKDR Hash Function
unsigned int BKDRHash(char *str)
{  unsigned int seed = 131; // 31 131 1313 13131 131313 etc..  unsigned int hash = 0;  while (*str)  {  hash = hash * seed + (*str++);  }  return (hash & 0x7FFFFFFF);
}  

本题hash解法 n^2

#define ULL unsigned long long
const int maxn = 5111 * 2;const int HASH = 10007;
struct HashMap{int head[HASH];int next[maxn];ULL state[maxn];int num_s1[maxn];int num_s2[maxn];int sz;void init(){sz = 0;memset(head, -1, sizeof(head));}int insert(ULL val, bool info){int h = val % HASH;for (int i = head[h]; i != -1; i = next[i]){if (val == state[i]){if (info) num_s1[i]++;else num_s2[i]++;return 1;///存在}}num_s1[sz] = 0;num_s2[sz] = 0;state[sz] = val;next[sz] = head[h];if (info) num_s1[sz]++;else num_s2[sz]++;head[h] = sz++;return 0;///不存在}bool check(){for (int i = 0; i < sz; i++){if (num_s1[i] == num_s2[i] && num_s1[i] == 1)return true;}return false;}
}H;const int SEED = 13331;
ULL P[maxn];
ULL s1[maxn], s2[maxn];char sa[maxn], sb[maxn];void hash_pre(ULL P[])
{P[0] = 1;for (int i = 1; i <= maxn; i++)P[i] = P[i - 1] * SEED;
}
void hash_init(ULL s1[], char sa[])///sa[],下标从0開始;相应是s1[]的值得下标从1開始
{int n = strlen(sa);s1[0] = 0;for (int i = 1; i <= n; i++)s1[i] = s1[i - 1] * SEED + sa[i - 1];
}
ULL getSeg(ULL s1[], int l, int r)///求s1[]的下标区间的hash值
{return s1[r] - s1[l - 1] * P[r - l + 1];
}int main()
{hash_pre(P);RS(sa); RS(sb);int n = strlen(sa), m = strlen(sb);hash_init(s1, sa);hash_init(s2, sb);int fla = 0;int mn = min(n, m);for (int i = 1; i <= mn; i++){H.init();for (int j = i; j <= n; j++){H.insert(getSeg(s1, j - i + 1, j), 0);}for (int j = i; j <= m; j++){H.insert(getSeg(s2, j - i + 1, j), 1);}if (H.check()){printf("%d\n", i);fla = 1;break;}}if (!fla) puts("-1");return 0;
}

后缀数组:


const int MAXN = 5111 * 2;
const int INF = 0x3f3f3f3f;
int wa[MAXN], wb[MAXN], wv[MAXN], wn[MAXN];
//char r[MAXN];
int a[MAXN], sa[MAXN], rank[MAXN], height[MAXN];int cmp(int *r, int a,int b, int k)
{return r[a] == r[b] && r[a + k] == r[b + k];
}
void build_sa(int *r, int *sa, int n,int m)
{int i,j, p;int *x = wa, *y = wb, *t;for (int i= 0; i < m; i++) wn[i] = 0;for (int i= 0; i < n; i++) wn[x[i] = r[i]]++;for (int i = 1; i < m; i++) wn[i] += wn[i - 1];for (int i = n - 1; i >= 0; i--) sa[--wn[x[i]]] = i;for (p = 1, j = 1; p < n; j <<= 1, m = p){for (p = 0, i = n - j; i < n; i++) y[p++] = i;for (i = 0; i < n; i++) if (sa[i] >= j) y[p++] = sa[i] - j;for (i = 0; i < m; i++) wn[i] = 0;for (i = 0; i < n; i++) wn[wv[i] = x[y[i]]]++;for (i = 1; i < m; i++) wn[i] += wn[i - 1];for (i = n - 1; i >= 0; i--) sa[--wn[wv[i]]] = y[i];t = x; x = y; y = t;x[sa[0]] = 0; p = 1;for (i = 1; i < n; i++)x[sa[i]] = cmp(y, sa[i - 1], sa[i], j) ? p - 1 : p++;}
}
void getHeight(int *r, int *sa, int n)
{int i, j, k = 0;for (i = 1; i <= n; i++){rank[sa[i]] = i;height[i] = 0;}for (i = 0;i < n; i++){if (k) k--;j = sa[rank[i] - 1];while (r[i + k] == r[j + k]) k++;height[rank[i]] = k;}
}char ca[MAXN], cb[MAXN];void solve(int n)
{height[n + 1] = 0;int ans = INF;int l = strlen(ca);for (int i = 1; i <= n; i++){if (!height[i]) continue;if (sa[i] < l && sa[i - 1] < l) continue;if (sa[i] >= l && sa[i - 1] >= l) continue;int pre = height[i - 1] + 1;int next = height[i + 1] + 1;if (height[i] >= max(pre, next)){ans = min(ans, max(pre, next));}}if (ans == INF) puts("-1");else printf("%d\n", ans);
}
int main()
{int t, n, m;///n, mn = 0;m = 256;RS(ca);int l = strlen(ca);REP(j, l) a[n++] = (int)ca[j];a[n++] = m++;RS(cb);l = strlen(cb);REP(j, l) a[n++] = (int)cb[j];a[n++] = m++;a[--n] = 0; --m;build_sa(a, sa, n + 1, m);getHeight(a, sa, n);solve(n);return 0;
}
/*
0 8 0
1 6 0
2 4 2
3 2 4
4 0 6
5 7 0
6 5 1
7 3 3
8 1 5
^^^^^^^^^^^^^^0 4
1 8
2 3
3 7
4 2
5 6
6 1
7 5
8 0
^^^^^^^^^^^^^^
*/

cf244D. Match amp; Catch 字符串hash (模板)或 后缀数组。。。相关推荐

  1. 模板:后缀数组(SA)

    文章目录 前言 解析 后缀排序 优化1:基数排序 优化2:简化第一次排序 优化3:提前break 完整代码 LCP与height 所谓后缀数组,就是存储后缀的数组 (逃) 前言 为什么一个算法,如此难 ...

  2. 寻找一个字符串的重复子串 后缀数组

    什么是后缀数组 令字符串 S=S[1]S[2]...S[n]S=S[1]S[2]...S[n]{\displaystyle S=S[1]S[2]...S[n]} , S[i,j]S[i,j]{\dis ...

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

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

  4. 字符串系列(二)——“万金油”后缀数组

    学习后缀数组有感 (原创,转载请注明出处) 在做一些串的问题时,因为其本身处理比较麻烦,光是比较就要耗费O(n²)的复杂度.因此我们使用后缀数组来进行复杂度的简化. 首先要明确,后缀数组是一种工具,可 ...

  5. 后缀数组——处理字符串的有力工具,好好学习

    后缀数组--处理字符串的有力工具 作者:罗穗骞 2009年1月 [摘要] 后缀数组是处理字符串的有力工具.后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现,能够实现后缀树的很多功能而时间 ...

  6. 后缀数组——处理字符串的有力工具

    http://wenku.baidu.com/link?url=suTtOeeWF8n9eCvuZIFIHj6CSnAwEessZcHUlDD-YXZIbHE9R7VFOHFcNXnKPXDiDRhP ...

  7. 字符串hash(二)

    从上一届已经讲了字符串hash的方法,hash后怎么用也很重要 文章目录 一.查询子串的hash值 查询子串减去期中一个字符后的hash值 查询两个子串拼接的hash值 **hash的模板(自然溢出) ...

  8. 字符串hash(一)

    很久没遇到过hash的题了,今天来重新温故一下 文章目录 序言 常用的几个字符串hash方法: hash公式(自然溢出) 讲解 模板 单hash 讲解 模板 双hash 讲解 代码 总结 序言 你有没 ...

  9. 各种字符串Hash函数

    整理了一下几个字符串hash函数,使用了模板,使其支持宽字符串,代码如下: /// @brief BKDR Hash Function /// @detail 本算法由于在Brian Kernigha ...

最新文章

  1. 携程App for Apple Watch探索
  2. pytorch模型转换
  3. NOIP 2014 联合权值
  4. 124angular1实现无限表单(仅供自己看)
  5. javaWeb服务详解(含源代码,测试通过,注释) ——applicationContext-Service.xml
  6. 内存泄漏和内存溢出的区别
  7. 牛客网——奥运排序问题
  8. ajax+php 实现即时聊天
  9. java的程序员工资一般多少_JAVA程序员工资一般是多少
  10. RocksDB Compaction(一)介绍
  11. sidetone 、回声抑制
  12. 电池革命:固态电池量产还有多远?
  13. RabbitMQ配置文件_修改RabbitMQ MQTT的1883端口
  14. 移动开发即服务,腾讯云移动开发平台打造开发新模式
  15. 如何将自己做的网页发布到网站让别人可以看到
  16. python迭代器定义_Python-迭代器相关概念
  17. Espresso Idling Resource
  18. 动态规划石子排序java_动态规划之石子归并
  19. label 标签的巧妙使用
  20. 挖地兔股票数据接口 tushare 初接触

热门文章

  1. java 8 两个list_java集合框架综述
  2. strip python里面是什么意思_python中的strip是什么意思
  3. 零基础学python数据分析_Python学习指南:使用Python学习数据分析
  4. linux 图片编辑 java_Java的图片处理工具类
  5. html post 发送两次,jQuery Ajax发送两次第二次提交,发送三次三次
  6. mysql存储ip地址_MySQL怎样存储IP地址
  7. 安卓案例:联选系部与专业
  8. JavaScript学习笔记:对象
  9. 数据库笔记01:SQL Server系统概述
  10. 17.立体匹配——更好的效果与挑战,总结_5