Common Substrings POJ - 3415(长度不小于k的公共子串的个数)
题意:
给定两个字符串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 <cctype>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define rd(a) scanf("%d", &a)
#define rlld(a) scanf("%lld", &a)
#define rc(a) scanf("%c", &a)
#define rs(a) scanf("%s", a)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _ ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = , INF = 0x7fffffff;
int s[maxn];
int sa[maxn], t[maxn], t2[maxn], c[maxn], n;
int ran[maxn], height[maxn]; void get_sa(int m)
{
int i, *x = t, *y = t2;
for(i = ; i < m; i++) c[i] = ;
for(i = ; i < n; i++) c[x[i] = s[i]]++;
for(i = ; i < m; i++) c[i] += c[i-];
for(i = n-; i >= ; i--) sa[--c[x[i]]] = i;
for(int k = ; k <= n; k <<= )
{
int p = ;
for(i = n-k; i < n; i++) y[p++] = i;
for(i = ; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
for(i = ; i < m; i++) c[i] = ;
for(i = ; i < n; i++) c[x[y[i]]]++;
for(i = ; i< m; i++) c[i] += c[i-];
for(i = n-; i >= ; i--) sa[--c[x[y[i]]]] = y[i];
swap(x, y);
p = ; x[sa[]] = ;
for(i = ; i < n; i++)
x[sa[i]] = y[sa[i-]] == y[sa[i]] && y[sa[i-]+k] == y[sa[i]+k] ? p- : p++;
if(p >= n) break;
m = p;
}
int k = ;
for(i = ; i < n; i++) ran[sa[i]] = i;
for(i = ; i < n; i++)
{
if(k) k--;
int j = sa[ran[i]-];
while(s[i+k] == s[j+k]) k++;
height[ran[i]] = k;
}
} int k, top, num;
LL sum, ans;
char s1[maxn], s2[maxn];
int stac[maxn], cnt[maxn];
int main()
{
while(~rd(k) && k)
{
top = sum = num = ans = n = ;
rs(s1); rs(s2);
int len1 = strlen(s1);
int len2 = strlen(s2);
rep(i, , len1)
s[n++] = s1[i];
s[n++] = '#';
rep(i, , len2)
s[n++] = s2[i];
s[n++] = ;
get_sa();
rep(i, , n)
{
if(height[i] < k)
{
sum = top = ;
continue;
}
int num = ;
while(top && height[i] < stac[top]) //维持单调递增栈 可能当前sa[i-1] < len1 但height是连续的 所以短板效应替换栈中元素
{ //而它自己如果sa[i-1] < len1 那么下面的 num是不加1的 即自己不算在内
sum -= (LL)(stac[top] - k + ) * cnt[top];
sum += (LL)(height[i] - k + ) * cnt[top];
num += cnt[top];
top--;
}
stac[++top] = height[i];
if(sa[i-] > len1) //扫描B串
{
sum += (LL)(height[i] - k + );
cnt[top] = num + ;
}
else
cnt[top] = num;
if(sa[i] < len1)
ans += sum;
}
rep(i, , n)
{
if(height[i] < k)
{
sum = top = ;
continue;
}
int num = ;
while(top && height[i] < stac[top])
{
sum -= (LL)(stac[top] - k + ) * cnt[top];
sum += (LL)(height[i] - k + ) * cnt[top];
num += cnt[top];
top--;
}
stac[++top] = height[i];
if(sa[i-] < len1) //扫描A串
{
sum += (LL)(height[i] - k + );
cnt[top] = num + ;
}
else
cnt[top] = num;
if(sa[i] > len1)
ans += sum;
}
printf("%lld\n", ans); } return ;
}
Common Substrings POJ - 3415(长度不小于k的公共子串的个数)的更多相关文章
- POJ-Common Substrings(后缀数组-长度不小于 k 的公共子串的个数)
题意: 长度不小于 k 的公共子串的个数 分析: 基本思路是计算 A 的所有后缀和 B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于 k 的部分全部加起来. 先将两个字符串连起来,中间 ...
- POJ 3415 Common Substrings(长度不小于K的公共子串的个数+后缀数组+height数组分组思想+单调栈)
http://poj.org/problem?id=3415 题意:求长度不小于K的公共子串的个数. 思路:好题!!!拉丁字母让我Wa了好久!!单调栈又让我理解了好久!!太弱啊!! 最简单的就是暴力枚 ...
- POJ 3415 Common Substrings 【长度不小于 K 的公共子串的个数】
传送门:http://poj.org/problem?id=3415 题意:给定两个串,求长度不小于 k 的公共子串的个数 解题思路: 常用技巧,通过在中间添加特殊标记符连接两个串,把两个串的问题转换 ...
- 【POJ 3415】Common Substrings 长度不小于k的公共子串的个数
长度不小于k的公共子串的个数,论文里有题解,卡了一上午,因为sum没开long long!!! 没开long long毁一生again--- 以后应该早看POJ里的Discuss啊QAQ #inclu ...
- POJ - 3415 Common Substrings(后缀数组求长度不小于 k 的公共子串的个数+单调栈优化)
Description A substring of a string T is defined as: T( i, k)= TiTi+1... Ti+k-1, 1≤ i≤ i+k-1≤| T|. G ...
- poj 3415 后缀数组 两个字符串中长度不小于 k 的公共子串的个数
Common Substrings Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 11469 Accepted: 379 ...
- POJ 3415 不小于k的公共子串的个数
Common Substrings Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 9248 Accepted: 3071 ...
- Common Substrings POJ - 3415 (后缀自动机)
Common Substrings \[ Time Limit: 5000 ms\quad Memory Limit: 65536 kB \] 题意 给出两个字符串,要求两个字符串公共子串长度不小于 ...
- 【poj3415-长度不小于k的公共子串个数】后缀数组+单调栈
这题曾经用sam打过,现在学sa再来做一遍. 基本思路:计算A所有的后缀和B所有后缀之间的最长公共前缀. 分组之后,假设现在是做B的后缀.前面的串能和当前的B后缀产生的公共前缀必定是从前往后单调递增的 ...
随机推荐
- python中变量的数据类型总结
1.变量的数据类型,分为数值型和非数值型 数值型: int(整型) float(浮点型) bool (布尔型,只有True和Flase) compex(复数型, 用于科学计算) 非数值型: str(字 ...
- mysql查询当天,前一天,一周,一个月
当天 select * from 表名 where to_days(时间字段名) = to_days(now()); 昨天 SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ...
- docker 一篇文章学习容器化
什么是镜像?什么是容器? 一句话回答:镜像是类,容器是实例 docker 基本操作命令: 删除所有container: docker rm $(docker ps -a -q) 删 ...
- NO 18---- webpack 4.x 使用遇到的问题以及开发配置
最近在项目中用webpack的过程中老是出现问题,很是纳闷,按理说一直这样使用没有问题啊,经过我研究后发现,是因为在webpack更新到4.x之后,操作方式与之前相比变化很大.而我们使用npm默认安装 ...
- 【LeetCode算法题库】Day1:TwoSums & Add Two Numbers & Longest Substring Without Repeating Characters
[Q1] Given an array of integers, return indices of the two numbers such that they add up to a specif ...
- [C++]模板类和模板函数
参考: C++ 中模板使用详解 C++模板详解 概念 为了避免因重载函数定义不全面而带来的调用错误,引入了模板机制 定义 模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模 ...
- [shell] bash数组(for时排序)
for处理时会自动把顺序按A-Z排序了 [root@XM-v106 ~]# bash b.sh A -> B -> C -> D -> E -> [root@XM-v10 ...
- 看oracle的sid
ps -ef|grep pmon 可以从进程名字里看到 也可以通过 sqlplus / as sysdbashow parameter instance_name
- 实验三:敏捷开发与XP实践
Java实验三报告 一. 实验内容 (一)敏捷开发与XP 内容:1.敏捷开发(Agile Development)是一种以人为核心.迭代.循序渐进的开发方法. 2.极限编程(eXtreme Pro ...
- 20135231 JAVA实验报告三:敏捷开发与XP实践
---恢复内容开始--- JAVA实验报告三:敏捷开发与XP实践 20135231 何佳 实验内容 1. XP基础 2. XP核心实践 3. 相关工具 实验要求 1.没有Linux基础的同学建议先学习 ...