【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\)就可以了. 对于相同子串,我们能想 ...
随机推荐
- Python实现1-9数组形成的结果为100的所有运算式
问题: 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性.例如:1 + 2 + 34–5 + 67–8 + 9 = 100. f ...
- C#中加锁问题
今天在工作中遇到了一个问题 当我使用多线程访问同一个方法资源时,为了不对结果进行冲突于是加了个死锁,还遇到了一些坑,特此来进行一些记录 static object obj=new object(); ...
- CentOS7——防火墙设置
1.查看firewall服务状态 systemctl status firewalld 2.查看firewall的状态firewall-cmd --state 3.开启.重启.关闭.firewalld ...
- JavaScript中对象的属性:如何遍历属性
for/in 语句循环遍历对象的属性. js中获取key得到某对象中相对应的value的方法:obj.key js中根据动态key得到某对象中相对应的value的方法有二: 一.var key = & ...
- 计算机图形学(Conputer Graphics):非均匀有理B样条
计算机图形学(Conputer Graphics):非均匀有理B样条 非均匀有理B样条(Non-Uniform Rational B-Spline)英文缩写,NURBS. 它是贝塞尔曲线的一个推广,而 ...
- OpenCV2:第八章 界面事件
一.简介 OpenCV中提供了程序界面中的鼠标和键盘事件 二.鼠标事件 // 设置鼠标回调函数 void setMouseCallback ( const string& winname, ...
- 基于docker搭建wordpress博客网站平台
WordPress是使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站.也可以把 WordPress当作一个内容管理系统(CMS)来使用. WordPre ...
- lucene测试类
package test.lucene; import java.io.BufferedReader;import java.io.File;import java.io.FileInputStrea ...
- Python、机器学习、计算机视觉、深度学习入门
1.简明Python教程 2.Python计算机视觉编程 3.机器学习实践 4.吴恩达机器学习 5.李飞飞深度学习与计算机视觉
- day23 02 组合(继续人狗大战游戏)
day23 02 组合(继续人狗大战游戏) 面向对象的三大特性:继承 多态 封装 先讲解一下组合 组合:一个对象的属性值是另一个类的对象:对象.属性.属性(一般有两个点) 继续扩展day22 01里面 ...