Facer’s string
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 2155   Accepted: 644

Description

Minifacer was very happy these days because he has learned the algorithm of KMP recently. Yet his elder brother, Hugefacer, thought that Minifacer needs a deeper understanding of this algorithm. Thus Hugefacer decided to play a game with his little brother to enhance his skills.

First, Hugefacer wrote down two strings S1 and S2. Then Minifacer tried to find a substring S3 of S1 which meets the following requirements: 1) S3 should have a length of k (which is a constant value); 2) S3 should also be the substring of S2. After several rounds, Hugefacer found that this game was too easy for his clever little brother, so he added another requirement: 3) the extended string of S3 should NOT be the substring of S2. Here the extended string of S3 is defined as S3 plus its succeed character in S1 (if S3 does not have a succeed character in S1, the extended string of S3 is S3 + ' ' which will never appear in S2). For example, let S1 be "ababc", if we select the substring from the first character to the second character as S3 (so S3 equals "ab"), its extended string should be "aba"; if we select the substring from the third character to the fourth character as S3, its extended string should be "abc"; if we select the substring from the fourth character to the fifth character as S3, its extended string should be "bc".

Since the difficult level of the game has been greatly increased after the third requirement was added, Minifacer was not able to win the game and he thought that maybe none of the substring would meet all the requirements. In order to prove that Minifacer was wrong, Hugefacer would like to write a program to compute number of substrings that meet the three demands (Note that two strings with same appearance but different positions in original string S1 should be count twice). Since Hugefacer do not like characters, he will use non-negative integers (range from 0 to 10000) instead.

Input

There are multiple test cases. Each case contains three lines: the first line contains three integers nm and k where n represents the length of S1m represents the length of S2 and k represents the length of substring; the second line contains string S1 and the third line contains string S2. Here 0 ≤ nm ≤ 50000. Input ends with EOF.

Output

For each test case, output a number in a line stand for the total number of substrings that meet the three requirements.

Sample Input

5 5 2
1 2 1 2 3
1 2 3 4 5
5 5 3
1 2 1 2 3
1 2 3 4 5

Sample Output

2
1 题意:有两个字符串s1,s2,现在要从s1中找到子串s3,其长度必须大于等于K,使得s3也是s2的子串,并且s3再加上s1中的一个后继字符后不再是s2的子串,问满足条件的s3的数量。
思路:求出后缀数组和高度数组,那么对于s1中每一个后缀,判断这个后缀和s2中的任意一个后缀的lcp是否等于K。可以换个角度考虑这个问题,在lcp数组中,把数值大于等于K的连续的几个后缀的lcp当成一块来考虑,
如果这个块中s1,s2中的后缀都有,说明这些后缀当中的任意两个后缀的lcp都是大于等于K的,这样把lcp数组分成一块一块来考虑就能很快求出A中所有后缀和B中后缀的lcp大于等于K的数量,正好等于K的数量就是
sum(K)-sum(K+1)
AC代码:
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N_MAX = + ;
typedef long long ll;
int n, N,M, k, K;
int Rank[N_MAX * ];
int tmp[N_MAX * ];
int sa[N_MAX * ];
int lcp[N_MAX * ];
int s[N_MAX * ];
bool compare_sa(const int& i, const int& j) {
if (Rank[i] != Rank[j])return Rank[i] < Rank[j];
else {
int ri = i + k <= n ? Rank[i + k] : -;
int rj = j + k <= n ? Rank[j + k] : -;
return ri < rj;
}
} void construct_sa(const int *S, int *sa) {
for (int i = ; i <= n; i++) {
sa[i] = i;
Rank[i] = i < n ? S[i] : -;
}
for (k = ; k <= n; k *= ) {
sort(sa, sa + n + , compare_sa);
tmp[sa[]] = ;
for (int i = ; i <= n; i++) {
tmp[sa[i]] = tmp[sa[i - ]] + (compare_sa(sa[i - ], sa[i]) ? : );
}
for (int i = ; i <= n; i++) {
Rank[i] = tmp[i];
}
}
}
void construct_lcp(const int *S, int *sa, int *lcp) {
memset(lcp, , sizeof(lcp));
for (int i = ; i <= n; i++)Rank[sa[i]] = i;
int h = ;
lcp[] = ;
for (int i = ; i < n; i++) {
int j = sa[Rank[i] - ];
if (h > )h--;
for (; j + h < n&&i + h < n; h++) {
if (S[j + h] != S[i + h])break;
}
lcp[Rank[i] - ] = h;
}
} ll find_num(int K) {
int A = , B = ;
ll res = ;
for (int i = ; i < n;i++) {
if (lcp[i] < K) {
if (B > )res += A;
A = ; B = ;
}
if (sa[i + ] < N)A++;
if (sa[i + ] > N) B++;
}
return res;
} int main() {
while (scanf("%d%d%d", &N, &M, &K) != EOF) {
for (int i = ; i < N; i++) {
scanf("%d", &s[i]);
s[i]++;
}
s[N] = '$';
for (int i = N + ; i < N + M + ; i++) {
scanf("%d", &s[i]);
s[i]++;
}
n = N + M + ;
s[n] = ;
construct_sa(s, sa);
construct_lcp(s, sa, lcp);
printf("%lld\n",find_num(K)-find_num(K+));
}
return ;
}

poj 3729 Facer’s string的更多相关文章

  1. POJ3729 Facer’s string 后缀数组

                                                                                                      Fa ...

  2. HDU 3260/POJ 3827 Facer is learning to swim(DP+搜索)(2009 Asia Ningbo Regional)

    Description Facer is addicted to a game called "Tidy is learning to swim". But he finds it ...

  3. POJ 2887:Big String(分块)

    http://poj.org/problem?id=2887 题意:给出一个字符串,还有n个询问,第一种询问是给出一个位置p和字符c,要在位置p的前面插入c(如果p超过字符串长度,自动插在最后),第二 ...

  4. POJ 3336 Count the string (KMP+DP,好题)

    参考连接: KMP+DP: http://www.cnblogs.com/yuelingzhi/archive/2011/08/03/2126346.html 另外给出一个没用dp做的:http:// ...

  5. POJ - 3541 - Given a string…

    Given a string… Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 1819   Accepted: 390 C ...

  6. poj 2155 matrix 二维线段树 线段树套线段树

    题意 一个$n*n$矩阵,初始全为0,每次翻转一个子矩阵,然后单点查找 题解 任意一种能维护二维平面的数据结构都可以 我这里写的是二维线段树,因为四分树的写法复杂度可能会退化,因此考虑用树套树实现二维 ...

  7. POJ 3376 Finding Palindromes EX-KMP+字典树

    题意: 给你n个串串,每个串串可以选择和n个字符串拼接(可以自己和自己拼接),问有多少个拼接后的字符串是回文. 所有的串串长度不超过2e6: 题解: 这题由于是在POJ上,所以string也用不了,会 ...

  8. (转)ACM next_permutation函数

    转自 stven_king的博客 这是一个求一个排序的下一个排列的函数,可以遍历全排列,要包含头文件<algorithm>下面是以前的笔记  (1) int 类型的next_permuta ...

  9. next_permutation函数

    这是一个求一个排序的下一个排列的函数,可以遍历全排列,要包含头文件<algorithm>下面是以前的笔记    与之完全相反的函数还有prev_permutation  (1) int 类 ...

随机推荐

  1. Form表单提交,js验证

    Form表单提交,js验证 1,  Onclick() 2, Onsubmit() Button标签 input (属性 submit  button )标签 Input type=button    ...

  2. pytorch中torch.nn构建神经网络的不同层的含义

    主要是参考这里,写的很好PyTorch 入门实战(四)--利用Torch.nn构建卷积神经网络 卷积层nn.Con2d() 常用参数 in_channels:输入通道数 out_channels:输出 ...

  3. 数据库中where与having的区别

    从整体声明角度分析: “where”是一个约束声明,在查询数据库结果返回之前对数据库的查询条件做一个约束,即返回结果之前起作用,“where”后面不能跟聚合函数: “having”是一个过滤声明,在查 ...

  4. Python系列6之面向对象

    目录 生成器和迭代器 字符串格式化 内置函数vars 反射 面向对象编程 一. 生成器和迭代器  1. 生成器 生成器具有一种生成的能力,它仅仅代表着一种生成的能力,当我们需要使用的时候,才会通过迭代 ...

  5. 区间DP入门题目合集

      区间DP主要思想是先在小区间取得最优解,然后小区间合并时更新大区间的最优解.       基本代码: //mst(dp,0) 初始化DP数组 ;i<=n;i++) { dp[i][i]=初始 ...

  6. 硬件中断--DEBUG系列

    问题描述: 在线调试时,全速运行,程序进入硬件中断,查看堆栈窗口,发现是从A函数进去的.但是A函数应该没有问题的: 再次重复,发现是从B函数进去的,但是B函数之前运行起来也没有问题的,而且没有传入参数 ...

  7. zeppelin的数据集的优化

    前面我们介绍了zeppelin的修改,前面由于自己的原因,对zeppelin的修改过于多,现在由于优化了,我们两个类, 一个是zeppelin-server的NotebookServer的类的broa ...

  8. Android log 引发的血案

    今天调试代码,我打印了一个东西: Log.d("WelcomeActivity", res.str); 结果总是代码执行不到这一行的下一行,程序也没有挂掉.后来,我自己去想各种可能 ...

  9. android apk瘦身之 图片压缩 tinypng

    参考地址: http://blog.csdn.net/jy692405180/article/details/52409369 http://www.tuicool.com/articles/BraI ...

  10. 让菜鸡讲一讲费用流(EK)

    让我再讲一个故事吧. 又有一些小精灵要准备从银月城(S)迁徙到Nibel山(T). 这两个地方之间的道路构成了一个网络. 每个道路都有它自己的容量,这决定了每天有多少小精灵可以同时从这儿通过. 和上一 ...