【bzoj3238】[Ahoi2013]差异 后缀数组+单调栈
来源:互联网 发布:mysql增删改查的技巧 编辑:程序博客网 时间:2024/06/05 06:11
首先求出height数组,原式很明显可以化成一堆长度的和-两两LCP的和,所以我们考虑每个height能充当多少个区间的最小值即可,那么这个问题可以用单调栈解决,从左和从右各维护一个单调递增的单调栈,求出点i向左和向右分别最多能延伸多长。
注意:
1.height数组的[i,i]是要计入区间数的,因为我们查询lcp(i,j)的时候查询的是height数组中rank[i]+1~rank[j]的最小值,所以[i,i]这个区间其实在原串中是对应的两个后缀。
2.注意处理相等的情况,如果两边都是维护单调递增的单调栈的话,那么会少算一部分情况,所以我们一边用单调递增的,另一边用单调不降的就可以了。证明的话自己画个图应该能看出来。
#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm>#include<iostream>#define maxn 500010using namespace std;int sa[maxn],height[maxn],rank[maxn];int wa[maxn],wb[maxn],wc[maxn];char s[maxn];int st[maxn],l[maxn],r[maxn];int n,m,top;void get_sa(){m=200;int *x=wa,*y=wc,*t;for (int i=0;i<=m;i++) wb[i]=0;for (int i=1;i<=n;i++) wb[x[i]=s[i]]++;for (int i=1;i<=m;i++) wb[i]+=wb[i-1];for (int i=n;i>=1;i--) sa[wb[x[i]]--]=i;for (int j=1,p=0;p<n;j*=2,m=p){p=0;for (int i=n-j+1;i<=n;i++) y[++p]=i;for (int i=1;i<=n;i++) if (sa[i]>j) y[++p]=sa[i]-j;for (int i=0;i<=m;i++) wb[i]=0;for (int i=1;i<=n;i++) wb[x[y[i]]]++;for (int i=1;i<=m;i++) wb[i]+=wb[i-1];for (int i=n;i>=1;i--) sa[wb[x[y[i]]]--]=y[i];t=x;x=y;y=t;p=1;x[sa[1]]=1;for (int i=2;i<=n;i++) if (y[sa[i]]==y[sa[i-1]] && y[sa[i]+j]==y[sa[i-1]+j]) x[sa[i]]=p; else x[sa[i]]=++p;}}void get_height(){for (int i=1;i<=n;i++) rank[sa[i]]=i;int k=0;for (int i=1;i<=n;i++){if (k) k--;if (rank[i]==1) continue;int j=sa[rank[i]-1];while (s[i+k]==s[j+k]) k++;height[rank[i]]=k;}}int main(){scanf("%s",s+1);n=strlen(s+1);get_sa();get_height();height[0]=-1;height[n+1]=-1;top=1;st[1]=0;for (int i=1;i<=n;i++){while (top && height[st[top]]>=height[i]) top--;l[i]=st[top]+1;st[++top]=i;}top=1;st[1]=n+1;for (int i=n;i>=1;i--){while (top && height[st[top]]>height[i]) top--;r[i]=st[top]-1;st[++top]=i;}long long ans=0;for (int i=1;i<=n;i++) ans-=(long long)height[i]*(long long)(i-l[i]+1)*(long long)(r[i]-i+1)*2;for (int i=1;i<=n;i++) ans+=(long long)(n-i+1)*(n-1);printf("%lld\n",ans);return 0;}
0 0
- 【bzoj3238】[Ahoi2013]差异 后缀数组+单调栈
- 【bzoj3238】[Ahoi2013]差异 后缀数组+单调栈
- 【bzoj3238】【AHOI2013】【差异】【后缀数组+单调栈】
- 后缀数组+单调栈 【Ahoi2013】bzoj3238 差异
- [BZOJ3238][Ahoi2013]差异(后缀数组+单调栈||后缀自动机+树形dp)
- BZOJ3238: [Ahoi2013]差异(后缀数组)
- [BZOJ3238][Ahoi2013]差异(后缀自动机||后缀数组)
- 【BZOJ3238】【Ahoi2013】差异 后缀自动机
- [BZOJ3238] [AHOI2013] 差异 - 后缀自动机
- bzoj3238 [Ahoi2013]差异 后缀自动机
- 【BZOJ3238】差异,后缀数组+单调栈维护height
- BZOJ3238【后缀数组】【单调栈】
- BZOJ 3238 [Ahoi2013]差异 后缀数组+单调栈
- bzoj 3238: [Ahoi2013]差异(后缀数组+单调栈)
- [BZOJ3238][Ahoi2013][后缀自动机][树形DP]差异
- 【BZOJ3238】差异 后缀数组
- [Ahoi2013]差异 bzoj3238
- 【AHOI2013】【BZOJ3238】差异
- Python基础 基本数据类型
- js 找出当前元素所包含的最后一个元素节点(不是文本节点)
- Arduino 交通灯
- Python基础03 序列
- 各大网站CSS代码初始化集合
- 【bzoj3238】[Ahoi2013]差异 后缀数组+单调栈
- Python基础04 运算
- js返回,页面暂存
- ubuntu(虚拟机)中使用minicom
- 4-5 UVA1590 IP网络(IP Networks)
- 1657 圆的划分问题
- Python基础05 缩进和选择
- Aduino 物理按键使led灯泡点亮
- 学习笔记(3)——串