POJ.3145.Common Substrings(后缀数组 倍增 单调栈)
\(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{ht()},i入栈后要对所有ht[top-1]>=ht[i]的top-1改成ht[i],并且i出栈(期间减去当前多算的答案ht[top]-ht[top-1]),直到ht[top-1]<ht[top]
//6096K 704MS
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long LL;
const int N=2e5+10;
int n,sa[N],ht[N],rk[N],sa2[N],tm[N],sk[N],val[N],bel[N];
char s[N];
void Get_SA()
{
int *x=rk,*y=sa2,m=260;
for(int i=0; i<=m; ++i) tm[i]=0;
for(int i=1; i<=n; ++i) ++tm[x[i]=s[i]+1];
for(int i=1; i<=m; ++i) tm[i]+=tm[i-1];
for(int i=n; i; --i) sa[tm[x[i]]--]=i;
for(int p=0,k=1; k<n; k<<=1,m=p,p=0)
{
for(int i=n-k+1; i<=n; ++i) y[++p]=i;
for(int i=1; i<=n; ++i) if(sa[i]>k) y[++p]=sa[i]-k;
for(int i=0; i<=m; ++i) tm[i]=0;
for(int i=1; i<=n; ++i) ++tm[x[i]];
for(int i=1; i<=m; ++i) tm[i]+=tm[i-1];
for(int i=n; i; --i) sa[tm[x[y[i]]]--]=y[i];
std::swap(x,y), p=x[sa[1]]=1;
for(int i=2; i<=n; ++i)
x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p:++p;
if(p>=n) break;
}
for(int i=1; i<=n; ++i) rk[sa[i]]=i;
ht[1]=0;
for(int k=0,p,i=1; i<=n; ++i)
{
if(rk[i]==1) continue;
if(k) --k;
p=sa[rk[i]-1];
while(i+k<=n&&p+k<=n&&s[i+k]==s[p+k]) ++k;
ht[rk[i]]=k;
}
}
int main()
{
int k;
while(scanf("%d",&k),k)
{
scanf("%s",s+1); int l=strlen(s+1);
s[l+1]=1, scanf("%s",s+2+l), n=strlen(s+1);
Get_SA();
for(int i=2/*1*/; i<=n; ++i)
{
ht[i]-=k-1, bel[i]=sa[i]>l;
if(ht[i]<0) ht[i]=0;
}
LL res=0,tmp;
val[0]=-1;
for(int top,t=0; t<=1; ++t)
{
tmp=0, top=0;
for(int i=2/*1*/; i<=n; ++i)//ht[1]就是补充字符 计算不计算都行
{
if(bel[i]!=t) res+=tmp;
sk[++top]=bel[i]==t;
val[top]=ht[i+1];
tmp+=(LL)sk[top]*val[top];
while(val[top-1]>=val[top])
{
--top;
tmp-=(LL)(val[top]-val[top+1])*sk[top];//减去之前多余的贡献
val[top]=val[top+1], sk[top]+=sk[top+1];
}
}
}
printf("%lld\n",res);
}
return 0;
}
POJ.3145.Common Substrings(后缀数组 倍增 单调栈)的更多相关文章
- poj 3415 Common Substrings 后缀数组+单调栈
题目链接 题意:求解两个字符串长度 大于等于k的所有相同子串对有多少个,子串可以相同,只要位置不同即可:两个字符串的长度不超过1e5; 如 s1 = "xx" 和 s2 = &qu ...
- poj 3415 Common Substrings——后缀数组+单调栈
题目:http://poj.org/problem?id=3415 因为求 LCP 是后缀数组的 ht[ ] 上的一段取 min ,所以考虑算出 ht[ ] 之后枚举每个位置作为右端的贡献. 一开始想 ...
- poj 3415 Common Substrings —— 后缀数组+单调栈
题目:http://poj.org/problem?id=3415 先用后缀数组处理出 ht[i]: 用单调栈维护当前位置 ht[i] 对之前的 ht[j] 取 min 的结果,也就是当前的后缀与之前 ...
- 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 Common Substrings - 后缀数组 - 二分答案 - 单调栈
题目传送门 传送点I 传送点II 题目大意 给定串$A, B$,求$A$和$B$长度大于等于$k$的公共子串的数量. 根据常用套路,用一个奇怪的字符把$A$,$B$连接起来,然后二分答案,然后按mid ...
- POJ 3415 Common Substrings 后缀数组+并查集
后缀数组,看到网上很多题解都是单调栈,这里提供一个不是单调栈的做法, 首先将两个串 连接起来求height 求完之后按height值从大往小合并. height值代表的是 sa[i]和sa[i ...
- POJ - 3415 Common Substrings (后缀数组)
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 s ...
- POJ 3415 Common Substrings ——后缀数组
[题目分析] 判断有多少个长度不小于k的相同子串的数目. N^2显然是可以做到的. 其实可以维护一个关于height的单调栈,统计一下贡献,就可以了. 其实还是挺难写的OTZ. [代码] #inclu ...
- POJ3415 Common Substrings —— 后缀数组 + 单调栈 公共子串个数
题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS Memory Limit: 65536K ...
随机推荐
- 通过全备+主从同步恢复被drop的库或表
MySQL 中drop 等高危误操作后恢复方法 实验目的: 本次实验以恢复drop操作为例,使用不同方法进行误操作的数据恢复. 方法: 利用master同步(本文)] 伪master+Binlog+同 ...
- mac 报错Root chmod operation not permitted on file
系统:mac os 10.14.1 重启电脑 mac用户在升级系统之后,电脑启用了SIP(System Integrity Protection),增加了rootless机制,导致即使在root权限下 ...
- certificate expired
最近在测试802.1x,测试过程中,radius服务器端一直显示如下错误: (5) authenticate {(5) eap: Expiring EAP session with state 0 ...
- 如何利用github打造个人博客专属域名(文字版本)
1. 前言 此篇文章仅限于记录,不适合作为教程使用. 2. 步骤 2.1 先决条件 有github账号,有个人域名(可在万网购买),电脑本地安装有git环境 2.2 在github新建仓库.例如我的g ...
- Hive官方使用手册——新Hive CLI(Beeline CLI)
Hive官方使用手册——新Hive CLI(Beeline CLI) https://blog.csdn.net/maizi1045/article/details/79481686
- js学习、备忘
字符串使用单引号’abc’.(双引号也行.推荐:html→双引号,js→单引号)===严格等于.!==严格不等于if(x) 当x为undefined.null和0的时候都为false:需注意当x为0 ...
- linux下各目录的作用
这么久了,一直觉得对于linux的运作情况还是懵懵懂懂的样子,刚才专门又看了一下 linux 下各目录的作用,记下来,以备以后再忘了. 下面内容来自:http://www.linuxidc.com/L ...
- window 命令大全
运行操作 CMD命令:开始->运行->键入cmd或command(在命令行里可以看到系统版本.文件系统版本) CMD命令锦集 1. gpedit.msc-----组策略 2. ...
- js改变或添加className
js改变或添加className <style type="text/css"> .newDiv { font-weight: bold; } </style&g ...
- plsql developer连接Oracle报错ORA-12154: TNS:could not resolve the connect identifier specified
今日更改Oracle网络配置文件后使用plsql developer 尝试连接到Oracle出现报错 ORA-12154: TNS:could not resolve the connect iden ...