【AHOI2013】bzoj3238 差异
2017-05-01 18:27
316 查看
实际上只需要求出后缀两两之间的lcp之和。也就是求height数组所有区间的区间最小值之和。这样扫描一遍,用单调栈维护区间最小height值递增的序列的左端点即可,建出sa以后是O(n)的。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define LL long long const int maxn=500010; char s[maxn]; int sa[maxn],rank[maxn],height[maxn],f[maxn],sta[maxn],val[maxn],cnt[maxn],n; int main() { int p,m=26,top; LL ans=0,now=0; scanf("%s",s+1); n=strlen(s+1); for (int i=1;i<=n;i++) cnt[rank[i]=s[i]-'a'+1]++; for (int i=2;i<=m;i++) cnt[i]+=cnt[i-1]; for (int i=n;i;i--) sa[cnt[rank[i]]--]=i; for (int k=1;;k<<=1) { p=0; for (int i=n-k+1;i<=n;i++) f[++p]=i; for (int i=1;i<=n;i++) if (sa[i]>k) f[++p]=sa[i]-k; for (int i=1;i<=m;i++) cnt[i]=0; for (int i=1;i<=n;i++) cnt[rank[f[i]]]++; for (int i=2;i<=m;i++) cnt[i]+=cnt[i-1]; for (int i=n;i;i--) sa[cnt[rank[f[i]]]--]=f[i]; for (int i=1;i<=n;i++) f[i]=rank[i]; rank[sa[1]]=1; for (int i=2;i<=n;i++) if (f[sa[i]]!=f[sa[i-1]]||f[sa[i]+k]!=f[sa[i-1]+k]) rank[sa[i]]=rank[sa[i-1]]+1; else rank[sa[i]]=rank[sa[i-1]]; m=rank[sa ]; if (m>=n) break; } for (int i=1;i<=n;i++) { height[rank[i]]=height[rank[i-1]]; if (height[rank[i]]) height[rank[i]]--; while (s[i+height[rank[i]]]==s[sa[rank[i]-1]+height[rank[i]]]) height[rank[i]]++; } sta[top=1]=1; for (int i=2;i<=n;i++) { p=i; while (top&&height[i]<=val[top]) { now-=(LL)(p-sta[top])*(val[top]-height[i]); p=sta[top]; top--; } sta[++top]=p; val[top]=height[i]; now+=height[i]; ans-=now; } //printf("%lld\n",-ans); ans*=2; for (int i=1;i<=n;i++) ans+=(LL)3*i*(i-1)/2; printf("%lld\n",ans); }
相关文章推荐
- BZOJ 3238 [Ahoi2013]差异
- BZOJ.3238.[AHOI2013]差异(后缀自动机 树形DP or 后缀数组 单调栈)
- BZOJ 3238 AHOI2013 差异 后缀自动机
- bzoj 3238 [Ahoi2013]差异
- 【bzoj3238】[Ahoi2013]差异 后缀数组+单调栈
- BZOJ3238[Ahoi2013]差异
- BZOJ3238 Ahoi2013 差异 后缀自动机,后缀树,后缀数组解法三合一
- bzoj 3238 [Ahoi2013]差异 后缀数组+单调栈
- bzoj 3238: [Ahoi2013]差异(后缀数组+单调栈)
- 【BZOJ 3238】[Ahoi2013]差异 后缀自动机构造后缀树
- ●BZOJ 3238 [Ahoi2013]差异
- bzoj 3238: [Ahoi2013]差异
- bzoj 3238 ahoi2013差异 后缀数组
- BZOJ 3238 [Ahoi2013]差异 后缀自动机
- BZOJ3238: [Ahoi2013]差异
- BZOJ 3238 [Ahoi2013]差异(后缀自动机)
- [BZOJ3238][Ahoi2013]差异解题报告|后缀数组
- BZOJ 3238 [Ahoi2013]差异 后缀数组+单调栈
- bzoj 3238: [Ahoi2013]差异
- [后缀自动机][树形DP] BZOJ 3238: [Ahoi2013]差异