1087: Common Substrings (哈希)】的更多相关文章

1087: Common Substrings Time Limit:3000/1000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total Submissions:857   Accepted:112 [Submit][Status][Discuss] Description You are given two long strings A and B. They are comprised of lowerc…
http://poj.org/problem?id=3415 Common Substrings Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5805   Accepted: 1911 Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤i+k-1≤|T|. Given two strings A, B an…
Common Substrings Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤i+k-1≤|T|. Given two strings A, B and one integer K, we define S, a set of triples (i, j, k): S = {(i, j, k) | k≥K, A(i, k)=B(j, k)}. You are to give…
Common Substrings   Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤i+k-1≤|T|. Given two strings A, B and one integer K, we define S, a set of triples (i, j, k): S = {(i, j, k) | k≥K, A(i, k)=B(j, k)}. You are to giv…
题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 12240   Accepted: 4144 Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤i+k-1≤|T|. Given two stri…
Common Substrings \[ Time Limit: 5000 ms\quad Memory Limit: 65536 kB \] 题意 给出两个字符串,要求两个字符串公共子串长度不小于 \(k\) 的对数. 思路 对 \(S\) 串构建后缀自动机,然后利用 \(v \in u'son\),\(dp[u] += dp[v]\) 求出每个节点的 \(endpos\) 大小. 用 \(T\) 串在自动机上跑最长公共连续子串,假设现在在 \(T\) 串上匹配的最长部分是 \(t\),停在自…
题意: 给两个串\(A.B\),问你长度\(>=k\)的有几对公共子串 思路: 先想一个朴素算法: 把\(B\)接在\(A\)后面,然后去跑后缀数组,得到\(height\)数组,那么直接\(rmq\)就能\(O(1)\)得到任意两个\(A\)和\(B\)的LCP.如果\(LCP >= k\),那么这个串的贡献对数为\(LCP - k + 1\).但是这样遍历显然超时. 那么我们可以用单调栈优化这个问题: 我们构建一个递增的单调栈,那么栈顶就是最大,每个栈里的元素为贡献值\(height\)的…
[题目分析] 判断有多少个长度不小于k的相同子串的数目. N^2显然是可以做到的. 其实可以维护一个关于height的单调栈,统计一下贡献,就可以了. 其实还是挺难写的OTZ. [代码] #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <map> #include <set> #include <queue>…
后缀数组,看到网上很多题解都是单调栈,这里提供一个不是单调栈的做法, 首先将两个串 连接起来求height   求完之后按height值从大往小合并.  height值代表的是  sa[i]和sa[i-1] 的公共前缀长度,那么每次合并就是合并  i和i-1 那么在合并小的时候公共前缀更大的肯定已经都合并在一起,那么就可以直接统计了. #include<iostream> #include<cstdio> #include<algorithm> #include<…
长度不小于k的公共子串的个数,论文里有题解,卡了一上午,因为sum没开long long!!! 没开long long毁一生again--- 以后应该早看POJ里的Discuss啊QAQ #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N = 200003; int t1[N], t2[N], c[…
借用罗穗骞论文中的讲解: 计算A 的所有后缀和B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于k 的部分全部加起来.先将两个字符串连起来,中间用一个没有出现过的字符隔开.按height 值分组后,接下来的工作便是快速的统计每组中后缀之间的最长公共前缀之和.扫描一遍,每遇到一个B 的后缀就统计与前面的A 的后缀能产生多少个长度不小于k 的公共子串,这里A 的后缀需要用一个单调的栈来高效的维护.然后对A 也这样做一次. #include<cstdio> #include<io…
[题目链接] http://poj.org/problem?id=3415 [题意] A与B长度至少为k的公共子串个数. [思路] 基本思想是将AB各个后缀的lcp-k+1的值求和.首先将两个字符串拼接起来中间用未出现的字符隔开,划分height数组,这首先保证了每一组中字符串之间的公共子串至少有k长度,组与组之间互不干扰. 问题变成了求一个组中一个A串与之前B串形成的LCP(lcp-k+1)和一个B串与之前A串形成的LCP,问题是对称的,这里先解决第一个.用一个单调栈,栈中存放两个元素分别he…
后缀数组 求长度不小于k的公共子串的个数 代码: #include <stdio.h> #include <string.h> ; int len, len1; int wa[maxn], wb[maxn], wv[maxn], wd[maxn], sa[maxn]; int lcp[maxn], r[maxn], rank[maxn], height[maxn]; int cmp(int *r, int a, int b, int l){ return r[a] == r[b]…
题目链接 题意:求解两个字符串长度 大于等于k的所有相同子串对有多少个,子串可以相同,只要位置不同即可:两个字符串的长度不超过1e5; 如 s1 = "xx" 和 s2 = "xx",k = 1,这时s1[0] -> s2[0] 或s2[1],同理s1[1] 也可以对应两个,这时长度为1,当长度为2时,只能找出1个,所以总和为5; 思路:还是将两个字符串连接后求出height数组,只不过之后不能朴素地用O(n^2)枚举相同子串的长度在遍历height数组来得到…
后缀数组可解.使用单调栈优化. /* 3415 */ #include <iostream> #include <sstream> #include <string> #include <map> #include <queue> #include <set> #include <stack> #include <vector> #include <deque> #include <algor…
题目链接:http://poj.org/problem?id=3415 题目分类:后缀数组 题意:给出两个串和一个数字k,求两个串的公共字串大于等于k的数目 代码: //#include<bits/stdc++.h> #include<stdio.h> #include<math.h> #include<algorithm> #include<string.h> using namespace std; #define N 200005 #def…
题目传送门 传送点I 传送点II 题目大意 给定串$A, B$,求$A$和$B$长度大于等于$k$的公共子串的数量. 根据常用套路,用一个奇怪的字符把$A$,$B$连接起来,然后二分答案,然后按mid分组. 分完组考虑如何统计每一组的贡献. 对于每一组内每一对$(A_i , B_j)$考虑拆成两部分: $rank(A_i) < rank(B_j)$ $rank(A_i) > rank(B_j)$ 然后就可以从小到大枚举每一个串,然后考虑前面的$A_i$或$B_j$的贡献. 显然这个贡献从当前串…
题目链接 \(Description\) 求两个字符串长度不小于k的公共子串对数. \(Solution\) 求出ht[]后先减去k,这样对于两个后缀A',B',它们之间的贡献为min{ht(A)}(A'到B'ht[]的最小值). 维护一个栈,栈中ht从底到顶递减. 如果当前是求B中后缀i和前边A中子串的答案,那么记录之前的∑(ht(A)),这就是前边A对i的贡献. 然后更新这个栈,若ht[i]>ht[top],入栈即可 但不对B计算答案: 若ht[i]<=ht[top],因为公共子串是min…
http://poj.org/problem?id=3415 题意:求长度不小于K的公共子串的个数. 思路:好题!!!拉丁字母让我Wa了好久!!单调栈又让我理解了好久!!太弱啊!! 最简单的就是暴力枚举,算出LCP,那么这个LCP对答案的贡献就是$x-k+1$. 我们可以将height进行分组,大于等于k的在同一组,如果两个后缀的最长公共子串>=k,那么它们肯定在同一个组内.现在从头开始扫,每遇到A的后缀时,就统计一下它和它前面的B的后缀能组成多少长度>=k的公共子串,然后再反过来处理B的后缀…
传送门 后缀自动机基础题. 给两个字符串,让你求长度不小于kkk的公共子串的数量. 这题可以用后缀自动机解决废话 考虑对其中一个字串建出后缀自动机,然后用另一个在上面跑,注意到如果一个状态有贡献的话,从它到根的状态都会有贡献,因此我们给每个节点打一个懒标记最后再统计一次答案即可. 代码: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ri r…
传送门:http://poj.org/problem?id=3415 题意:给定两个串,求长度不小于 k 的公共子串的个数 解题思路: 常用技巧,通过在中间添加特殊标记符连接两个串,把两个串的问题转换为 一个串的问题按照 height 分组.这里有两种情况一.后缀排名中, B的后缀在后 A的后缀在前,那么 height 就是 B的后缀 与前面 A的后缀的最长相同长度二.后缀排名中,A的后缀在前 B的后缀在后,那么 height 就是 A 的后缀与 前面 B 的后缀的最长相同长度所以要扫两遍,分别…
http://poj.org/problem?id=3415 (题目链接) 题意 给定两个字符串 A 和 B,求长度不小于 k 的公共子串的个数(可以相同). Solution 后缀数组论文题... 基本思路是计算 A 的所有后缀和 B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于 k 的部分全部加起来.先将两个字符串连起来,中间用一个没有出现过的字符隔开.按 height 值分组后,接下来的工作便是快速的统计每组中后缀之间的最长公共前缀之和.扫描一遍,每遇到一个 B 的后缀就统…
题意: 给定两个字符串A 和 B, 求长度不小于 k 的公共子串的个数(可以相同) 分两部分求和sa[i-1] > len1  sa[i] < len1  和  sa[i-1] < len1   sa[i] > len1 #include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include &l…
原题链接 注意:2号和3号get_next()函数中next[i]赋值时的区别,一个是0,一个是1,且不能互换 #include<cstdio> #include<cstring> #include<iostream> using namespace std; ; *maxn]; char s[maxn],t[maxn]; *maxn]; /*1. void get_next(char *s) { next[1]=0; //printf("%d\n"…
Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤i+k-1≤|T|. Given two strings A, B and one integer K, we define S, a set of triples (i, j, k): S = {(i, j, k) | k≥K, A(i, k)=B(j, k)}. You are to give the value of |S| f…
http://poj.org/problem?id=3415 给定两个字符串A 和B,求长度不小于k 的公共子串的个数(可以相同). 论文题,和上道题(POJ2774)类似,首先想到现将AB串合并,然后子串可以表示成字符串后缀的前缀,于是我们比较任意两个A后缀和B后缀,用height求出他们的公共子串长度就很好做了. (不懂为什么好做的可以看SPOJ694) 那么最坏的想法就是每遇到B后缀就和前面遇到的A后缀比较,这样显然TLE,也没用到height数组的优越性. 但是我们A后缀可以用单调栈维护…
题目:http://poj.org/problem?id=3415 因为求 LCP 是后缀数组的 ht[ ] 上的一段取 min ,所以考虑算出 ht[ ] 之后枚举每个位置作为右端的贡献. 一开始想的是把两个数组接起来(中间加个逗号之类的,就能算出正确的 LCP ),不加区分地算了贡献之后再分别减去两个数组自己内部的贡献. 看看题解,得知可以在那个接起来的数组上分别算 a 与前面的 b .b 与前面的 a 的贡献,就不用容斥了. 考虑怎么算贡献.一开始想的是取 min 一定越取越小,所以维护双…
常见的子串 时间限制: 5000MS   内存限制: 65536K 提交总数: 11942   接受: 4051 描述 字符串T的子字符串被定义为: Ť(我,ķ)= Ť 我 Ť 我 1 ... Ť I + K -1,1≤ 我 ≤ I + K -1≤| T |. 给定两个字符串A,B和一个整数K,我们定义S,一组三元组(i,j,k): S = {(i,j,k)| ķ ≥ ķ,甲(我,ķ)= 乙(Ĵ,ķ)}. 你要给的价值| S | 特定甲,乙和ķ. 输入 输入文件包含几个数据块.对于每个块,第一行…
这道是求长度不小于 k 的公共子串的个数...很不幸,我又TLE了... 解法参考论文以及下面的链接 http://www.cnblogs.com/vongang/archive/2012/11/20/2778481.html http://hi.baidu.com/fpkelejggfbfimd/item/5c76cfcba28fba26e90f2ea6 ; var c,h,rank,sa,x,y,stack:..maxn] of longint; n,k,top:longint; a,b,d…
题目:http://poj.org/problem?id=3415 先用后缀数组处理出 ht[i]: 用单调栈维护当前位置 ht[i] 对之前的 ht[j] 取 min 的结果,也就是当前的后缀与之前后缀的LCP,其中长度 >= K 的加到答案: 因为单调栈中是一段一段阶梯状的,只存了一段端点的位置,所以再记录一个 cnt 表示这一段的长度,算贡献时乘上 cnt: 因为是两个串之间,所以先统计 B 在 A 排名前的答案,再重复一遍统计 A 在 B 排名前的答案: 但是 ht[i] 是 sa[i]…