【POJ3415】Common Substrings(后缀数组,单调栈)
题意:

n<=1e5
思路:

我的做法和题解有些不同
题解是维护A的单调栈算B的贡献,反过来再做一次
我是去掉起始位置不同这个限制条件先算总方案数,再把两个串内部不合法的方案数减去
式子展开之后是 sigma(lcp(i,j))-K*L*(L+1)/2+合法(i,j)对数,其中L为连续的height[i]>=K的区域长度
sigma(lcp(i,j))计算部分与BZOJ3238类似
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define fi first
#define se second
#define MP make_pair
#define N 210000
#define MOD 1000000007
#define eps 1e-8
#define pi acos(-1)
#define oo 1000000000 char a[N],b[N];
int n,i,s[N],sa[N],wa[N],wb[N],wc[N],wd[N],height[N],rank[N],
H[N],stk[N];
ll ans,K,c[N],d[N]; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} 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,j,p;
for(i=;i<n;i++) wc[x[i]=r[i]]++;
for(i=;i<m;i++) wc[i]+=wc[i-];
for(i=n-;i>=;i--) sa[--wc[x[i]]]=i;
for(j=,p=;p<n;j*=,m=p)
{
p=;
for(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<n;i++) wd[i]=x[y[i]];
for(i=;i<m;i++) wc[i]=;
for(i=;i<n;i++) wc[wd[i]]++;
for(i=;i<m;i++) wc[i]+=wc[i-];
for(i=n-;i>=;i--) sa[--wc[wd[i]]]=y[i];
swap(x,y);
p=; x[sa[]]=;
for(i=;i<n;i++) x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
} void getheight(int *r,int *sa,int n)
{
int i,j,k=;
for(i=;i<=n;i++) rank[sa[i]]=i;
for(i=;i<n;height[rank[i++]]=k)
{
if(k) k--;
j=sa[rank[i]-];
while(r[i+k]==r[j+k]) k++;
}
} void init()
{
memset(s,,sizeof(s));
memset(sa,,sizeof(sa));
memset(wa,,sizeof(wa));
memset(wb,,sizeof(wb));
memset(wc,,sizeof(wc));
memset(wd,,sizeof(wd));
memset(height,,sizeof(height));
memset(rank,,sizeof(rank));
} void solve(ll f,int L,int R)
{
//printf("%lld %d %d\n",f,L,R);
for(int i=L-;i<=R+;i++) H[i]=height[i];
for(int i=L;i<=R;i++) c[i]=d[i]=;
stk[]=L-; H[L-]=-oo;
int top=;
for(int i=L;i<=R;i++)
{
while(top&&H[i]<H[stk[top]]) top--;
if(stk[top]==L-) c[i]=L;
else c[i]=stk[top]+;
stk[++top]=i;
}
stk[]=R+; H[R+]=-oo;
top=;
for(int i=R;i>=L;i--)
{
while(top&&H[i]<=H[stk[top]]) top--;
if(stk[top]==R+) d[i]=R;
else d[i]=stk[top]-;
stk[++top]=i;
}
ll tmp=;
for(int i=L;i<=R;i++) tmp=tmp+(-c[i]+i+)*(d[i]-i+)*height[i];
// printf("%lld\n",tmp);
ll t=R-L+;
tmp=tmp-K*(t+)*t/;
// printf("%lld\n",tmp);
for(int i=L;i<=R;i++) tmp=tmp+(-c[i]+i+)*(d[i]-i+);
// printf("%lld\n",tmp);
ans=ans+f*tmp;
} int main()
{
freopen("poj3415.in","r",stdin);
freopen("poj3415.out","w",stdout);
while(scanf("%lld",&K)!=EOF)
{
if(K==) break;
ans=;
init();
scanf("%s",a);
int n1=strlen(a);
scanf("%s",b);
int n2=strlen(b);
for(int i=;i<n1;i++)
if('A'<=a[i]&&a[i]<='Z') s[i]=a[i]-'A'+;
else s[i]=a[i]-'a'+;
s[n1]=;
n=n1;
getsa(s,sa,n+,);
getheight(s,sa,n); int i=;
while(i<n)
{
i++;
if(height[i]>=K)
{
int st=i;
while(i<=n&&height[i]>=K) i++;
if(st<=i-) solve(-,st,i-);
}
}
//printf("%lld\n",ans); init();
for(int i=;i<n2;i++)
if('A'<=b[i]&&b[i]<='Z') s[i]=b[i]-'A'+;
else s[i]=b[i]-'a'+;
s[n2]=;
n=n2;
getsa(s,sa,n+,);
getheight(s,sa,n);
i=;
while(i<n)
{
i++;
if(height[i]>=K)
{
int st=i;
while(i<=n&&height[i]>=K) i++;
if(st<=i-) solve(-,st,i-);
}
}
// printf("%lld\n",ans); init();
for(int i=;i<n1;i++)
if('A'<=a[i]&&a[i]<='Z') s[i]=a[i]-'A'+;
else s[i]=a[i]-'a'+;
s[n1]=;
for(int i=;i<n2;i++)
if('A'<=b[i]&&b[i]<='Z') s[n1+i+]=b[i]-'A'+;
else s[n1+i+]=b[i]-'a'+;
s[n1+n2+]=;
n=n1+n2+;
getsa(s,sa,n+,);
getheight(s,sa,n);
// for(int i=1;i<=n;i++) printf("%d\n",sa[i]);
i=;
while(i<n)
{
i++;
if(height[i]>=K)
{
int st=i;
while(i<=n&&height[i]>=K) i++;
if(st<=i-) solve(,st,i-);
}
}
//for(int i=0;i<=n1+n2;i++) printf("%d\n",sa[i]);
//for(int i=2;i<=n1+n2+2;i++) printf("%d\n",height[i]);
printf("%lld\n",ans);
}
return ;
}
【POJ3415】Common Substrings(后缀数组,单调栈)的更多相关文章
- POJ3415 Common Substrings —— 后缀数组 + 单调栈 公共子串个数
题目链接:https://vjudge.net/problem/POJ-3415 Common Substrings Time Limit: 5000MS Memory Limit: 65536K ...
- POJ3415 Common Substrings(后缀数组 单调栈)
借用罗穗骞论文中的讲解: 计算A 的所有后缀和B 的所有后缀之间的最长公共前缀的长度,把最长公共前缀长度不小于k 的部分全部加起来.先将两个字符串连起来,中间用一个没有出现过的字符隔开.按height ...
- 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 的结果,也就是当前的后缀与之前 ...
- poj3415 Common Substrings (后缀数组+单调队列)
Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 9414 Accepted: 3123 Description A sub ...
- 【BZOJ-3238】差异 后缀数组 + 单调栈
3238: [Ahoi2013]差异 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1561 Solved: 734[Submit][Status] ...
- BZOJ_3879_SvT_后缀数组+单调栈
BZOJ_3879_SvT_后缀数组+单调栈 Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个 ...
- BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈
BZOJ_3238_[Ahoi2013]差异_后缀数组+单调栈 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao ...
- BZOJ.4199.[NOI2015]品酒大会(后缀数组 单调栈)
BZOJ 洛谷 后缀自动机做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 显然只需要考虑极长的相同子串的贡献,然后求后缀和/后缀\(\max\)就可以了. 对于相同子串,我们能想 ...
随机推荐
- ftpaccess - ftpd的配置档
描述 DESCRIPTION 这个ftpaccess档案是用来配置下述功能的运作 存取功能(AccessCapabilities) autogroup<群组名称><类别>[&l ...
- URL URI URN的区别
下面这张图可以完美的解释他们三者之间的关系 URI包含URL和URN Uniform Resource Identifier :统一资源标志符,用于标识某一互联网资源 Uniform Resoutce ...
- 测试框架 Mocha 实例教程(转载:来自阮一峰的一篇文章)
Mocha(发音"摩卡")诞生于2011年,是现在最流行的JavaScript测试框架之一,在浏览器和Node环境都可以使用. 所谓"测试框架",就是运行测试的 ...
- prototype中的ajax异步加载
jquery前台处理: var param = {a:a}; $.post("*.do",param,function(data) { var columHtml = " ...
- 大数据学习系列之Hadoop、Spark学习线路(想入门大数据的童鞋,强烈推荐!)
申明:本文出自:http://www.cnblogs.com/zlslch/p/5448857.html(该博客干货较多) 1 Java基础: 视频方面: 推荐<毕向东JAVA ...
- centos 7 中文乱码的解决办法
@@首先查看系统的操作版本,我的版本是centos 7.2 的. @@查看系统是否有安装中文语言包,一般我们在安装的时候系统都会默认的为我们安装上去的. locale -a | grep " ...
- 如何利用 CSS 动画原理,在页面上表现日蚀现象
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/OELvrK 可交互视频教 ...
- include/autoconfig.mk
把autoconfig.mk和/include/configs/ $(obj)include/autoconf.mk.dep: $(obj)include/config.h include/commo ...
- 基于IAR移植sdk12.2.0建立nrf52832的工程———GPIO
工程伊始,需要在sdk包中拷贝三个重要的文件,blinky_iar_nRF5x.icf,iar_startup_nrf52.s,system_nrf52.c. 工程目录建立: 1.建立bsp文件,包括 ...
- WIN10配置instantclient
在PLSQL Developer目录下建立如下bat文件,替换其快捷方式,启动PLSQL Developer: @echo off set path=C:\instantclient-basic-nt ...