题目链接: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. PHP - 接口 - 单一接口

    /* * 接口的使用 */ //定义接口 interface IPerosn{ public function eat(); public function water(); } //定义继承自接口的 ...

  2. 使用ItextSharp产PDF完整操作

    原文 使用ItextSharp产PDF完整操作 记得上回有写到用C#操作Excel(.net 4.0) 很多朋友说推荐用NPOI,的确,用微软自带的操作execl会有很大的问题.客户的主机不愿意安装e ...

  3. 如何捕获winform程序全局异常?(续)

    前言 上篇文章我提供了一种方案可以供我们捕获单线程程序中的所有未处理异常.但是如果程序是多线程,那么新增线程出现了异常上个方案就无能为力了.本着方案总比问题多的态度,我再给大家提供一种新的方案,供大家 ...

  4. OpenProcessToken令牌函数使用方法

    >GetCurrentProcessID 得到当前进程的ID OpenProcessToken得到进程的令牌句柄LookupPrivilegeValue 查询进程的权限AdjustTokenPr ...

  5. lua 与 php 通过AES数据加密进行通讯

    近期公司有款<围住神经猫>的微信小游戏火爆的不行!公司又决定开发一系列的神经猫的小游戏,于是,我被拉过来了. 后来使用cocos-2dx 开发一款小游戏,client用的是lua脚本,为了 ...

  6. Qt递归拷贝和删除目录

    最近在翻看项目代码时,看到了这两个函数,想到这个功能十分常用,因此拿出来与大家分享,希望对大家有用.几点说明: 1.记得当初写代码那会,是参考了网上的帖子写的,做了一点小修改.因此代码源于网络. 2. ...

  7. Java+7入门经典 - 6 扩展类与继承 Part 1/2

    第6章 扩展类与继承 面向对象编程的一个重要特性: 允许基于已定义的类创建新的类; 6.1 使用已有的类 派生 derivation, 派生类 derived class, 直接子类 direct s ...

  8. Hadoop2.0/YARN深入浅出(Hadoop2.0、Spark、Storm和Tez)

    随着云计算.大数据迅速发展,亟需用hadoop解决大数据量高并发访问的瓶颈.谷歌.淘宝.百度.京东等底层都应用hadoop.越来越多的企 业急需引入hadoop技术人才.由于掌握Hadoop技术的开发 ...

  9. 基于visual Studio2013解决C语言竞赛题之1092链表转换

        题目 解决代码及点评 /************************************************************************/ /* ...

  10. struts2 <s:iterator/>怎样取得循环的索引

    <s:iterator value="list" id="user" status="L"> <s:property va ...