题目链接: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
#define LL long long int wa[N],wb[N],wm[N],wv[N],sa[N];
int *rank,height[N],s[N],a[N];
//sa:字典序中排第i位的起始位置在str中第sa[i]
//rank:就是str第i个位置的后缀是在字典序排第几
//height:字典序排i和i-1的后缀的最长公共前缀 bool cmp(int *r,int a,int b,int l)
{
return r[a] == r[b] && r[a+l] == r[b+l];
} void getsa(int *r,int *sa,int n,int m)
{
int *x=wa,*y=wb,*t;
for(int i=; i<m; ++i)wm[i]=;
for(int i=; i<n; ++i)wm[x[i]=r[i]]++;
for(int i=; i<m; ++i)wm[i]+=wm[i-];
for(int i=n-; i>=; --i)sa[--wm[x[i]]]=i;
for(int i=,j=,p=; p<n; j=j*,m=p)
{
for(p=,i=n-j; i<n; ++i)y[p++]=i;
for(i=; i<n; ++i)if(sa[i]>=j)y[p++]=sa[i]-j;
for(i=; i<m; ++i)wm[i]=;
for(i=; i<n; ++i)wm[x[y[i]]]++;
for(i=; i<m; ++i)wm[i]+=wm[i-];
for(i=n-; i>=; --i)sa[--wm[x[y[i]]]]=y[i];
for(t=x,x=y,y=t,i=p=,x[sa[]]=; i<n; ++i)
{
x[sa[i]]=cmp(y,sa[i],sa[i-],j)?p-:p++;
}
}
rank=x;
} void getheight(int *r,int *sa,int n)
{
for(int i=,j=,k=; i<n; height[rank[i++]]=k)
{
for(k?--k:,j=sa[rank[i]-]; r[i+k] == r[j+k]; ++k);
}
}
int k;
char s1[N];
int len1; LL solve(int n,int len,int k)
{
int *mark=wa,*sta=wb,top=,i;
LL sum=,num[]= {};
for(i = ;i<=n;i++)
{
if(height[i]<k)
{
top = num[] = num[] =;
}
else
{
for(int size = top; size&&sta[size]>height[i]-k+; size--)
{
num[mark[size]] += height[i]-k+-sta[size];
sta[size] = height[i]-k+;
}
sta[++top] = height[i]-k+;
if(sa[i-]<len) mark[top] = ;
if(sa[i-]>len) mark[top] = ;
num[mark[top]]+=height[i]-k+;
if(sa[i]<len) sum+=num[];
if(sa[i]>len) sum+=num[];
}
}
return sum;
} int main()
{
int i,j;
while(~scanf("%d",&k),k)
{
scanf("%s",s1);
int n = ;
for(n = ;s1[n]!='\0';n++)
s[n] = s1[n];
s[len1=n] = '#';
scanf("%s",s1+n+);
n++;
for(;s1[n]!='\0';n++)
s[n] = s1[n];
s[n] = ;
getsa(s,sa,n+,);
getheight(s,sa,n);
printf("%lld\n",solve(n,len1,k));
}
return ;
}

poj 3415 Common Substrings的更多相关文章

  1. POJ 3415 Common Substrings(后缀数组 + 单调栈)题解

    题意: 给两个串\(A.B\),问你长度\(>=k\)的有几对公共子串 思路: 先想一个朴素算法: 把\(B\)接在\(A\)后面,然后去跑后缀数组,得到\(height\)数组,那么直接\(r ...

  2. poj 3415 Common Substrings(后缀数组+单调栈)

    http://poj.org/problem?id=3415 Common Substrings Time Limit: 5000MS   Memory Limit: 65536K Total Sub ...

  3. 字符串(后缀数组):POJ 3415 Common Substrings

    Common Substrings   Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤ ...

  4. POJ 3415 Common Substrings 【长度不小于 K 的公共子串的个数】

    传送门:http://poj.org/problem?id=3415 题意:给定两个串,求长度不小于 k 的公共子串的个数 解题思路: 常用技巧,通过在中间添加特殊标记符连接两个串,把两个串的问题转换 ...

  5. poj 3415 Common Substrings - 后缀数组 - 二分答案 - 单调栈

    题目传送门 传送点I 传送点II 题目大意 给定串$A, B$,求$A$和$B$长度大于等于$k$的公共子串的数量. 根据常用套路,用一个奇怪的字符把$A$,$B$连接起来,然后二分答案,然后按mid ...

  6. POJ 3415 Common Substrings(长度不小于K的公共子串的个数+后缀数组+height数组分组思想+单调栈)

    http://poj.org/problem?id=3415 题意:求长度不小于K的公共子串的个数. 思路:好题!!!拉丁字母让我Wa了好久!!单调栈又让我理解了好久!!太弱啊!! 最简单的就是暴力枚 ...

  7. poj 3415 Common Substrings——后缀数组+单调栈

    题目:http://poj.org/problem?id=3415 因为求 LCP 是后缀数组的 ht[ ] 上的一段取 min ,所以考虑算出 ht[ ] 之后枚举每个位置作为右端的贡献. 一开始想 ...

  8. poj 3415 Common Substrings —— 后缀数组+单调栈

    题目:http://poj.org/problem?id=3415 先用后缀数组处理出 ht[i]: 用单调栈维护当前位置 ht[i] 对之前的 ht[j] 取 min 的结果,也就是当前的后缀与之前 ...

  9. POJ 3415 Common Substrings ——后缀数组

    [题目分析] 判断有多少个长度不小于k的相同子串的数目. N^2显然是可以做到的. 其实可以维护一个关于height的单调栈,统计一下贡献,就可以了. 其实还是挺难写的OTZ. [代码] #inclu ...

随机推荐

  1. char、signed char 和 unsigned char 的区别

    ANSI C 提供了3种字符类型,分别是char.signed char.unsigned char.而不是像short.int一样只有两种(int默认就是signed int). 三者都占1个字节( ...

  2. RVCT的Linux环境变量配置 ARM® RVDS™ 4.1(b713)

    下载解压 armrvds.tar.gz到/opt 下 在自己的build.sh下导入RVCT的环境变量配置ARM® RVDS™4.1(b713): export ARMROOT=/opt/armrvd ...

  3. cocos2d-x游戏开发系列教程-中国象棋05-开始游戏

    前情回顾 通过CCMainMenu的init函数,已经把所有的按钮,棋子都摆放完毕了,但是这个时候,棋子是不能走动的,只有在开始游戏之后才能移动棋子. 点击

  4. 使用 HTML5 webSocket API实现即时通讯的功能

    project下载地址:http://download.csdn.net/detail/wangshuxuncom/6430191 说明: 本project用于展示怎样使用 HTML5 webSock ...

  5. (1)ActivityThread分析

    1. 入口. 曾经一直都说Activity的人口是onCreate方法.事实上android上一个应用的入口,应该是ActivityThread.和普通的java类一样,入口是一个main方法. pu ...

  6. Android使用学习之画图(Canvas,Paint)与手势感应及其应用(乒乓球小游戏)

    作为一个没有学习Android的菜鸟,近期一直在工作之外努力地学习的Android的使用. 这周看了下Android的画图.主要是Canvas,Paint等,感觉须要实践下.下午正好有空,就想整一个乒 ...

  7. [置顶] c#验证码识别、图片二值化、分割、分类、识别

    c# 验证码的识别主要分为预处理.分割.识别三个步骤 首先我从网站上下载验证码 处理结果如下: 1.图片预处理,即二值化图片 *就是将图像上的像素点的灰度值设置为0或255. 原理如下: 代码如下: ...

  8. DELPHI语法基础学习笔记-Windows 句柄、回调函数、函数重载等(Delphi中很少需要直接使用句柄,因为句柄藏在窗体、 位图及其他Delphi 对象的内部)

    函数重载重载的思想很简单:编译器允许你用同一名字定义多个函数或过程,只要它们所带的参数不同.实际上,编译器是通过检测参数来确定需要调用的例程.下面是从VCL 的数学单元(Math Unit)中摘录的一 ...

  9. properties 文件的中文转ASCII

     在软件开发过程中,经常要涉及到多语言支持问题,常用的解决方案是将各个语言文字放到properties文件中,但中文是需要转为ASCII的 .那么如何将中文进行转换呢,下面就为你列举几种比较方便的方法 ...

  10. State Design Pattern 状态设计模式

    设置好内部状态,然后依据不同的函数作为行为模式,进行状态转换. 有点像Finite Automata算法,两者的思想是一样的. 会Finite Automata,那么这个设计模式就非常easy了. # ...