[后缀数组] BZOJ4650: [Noi2016] 优秀的拆分
来源:互联网 发布:崩坏学园漫画淘宝 编辑:程序博客网 时间:2024/05/22 07:44
令
那么答案就是
枚举A的长度
#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>using namespace std;typedef long long ll;const int N=100010;int t,n;char a[N];int t1[N],t2[N],c[N],lg2[N];struct SufArr{ int sa[N],height[N],rank[N]; int st[N][20]; void build(){ int *x=t1,*y=t2,m=26; for(int i=0;i<=m;i++) c[i]=0; for(int i=1;i<=n;i++) c[x[i]=a[i]-'a'+1]++; for(int i=1;i<=m;i++) c[i]+=c[i-1]; for(int i=n;i;i--) sa[c[x[i]]--]=i; for(int k=1;k<=n;k<<=1){ int 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++) c[i]=0; for(int i=1;i<=n;i++) c[x[y[i]]]++; for(int i=1;i<=m;i++) c[i]+=c[i-1]; for(int i=n;i;i--) sa[c[x[y[i]]]--]=y[i]; swap(x,y); p=1; x[sa[1]]=1; for(int i=2;i<=n;i++) x[sa[i]]=(y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])?p:++p; if(p>=n) break; m=p; } } void GetHeight(){ int k=0,j; for(int i=1;i<=n;i++) rank[sa[i]]=i; for(int i=1;i<=n;height[rank[i++]]=k) for(k?k--:0,j=sa[rank[i]-1];a[i+k]==a[j+k];k++); } void Pre(){ int t=lg2[n]; for(int i=1;i<=n;i++) st[i][0]=height[i]; for(int k=1;k<=t;k++) for(int i=1;i+(1<<k)-1<=n;i++) st[i][k]=min(st[i][k-1],st[i+(1<<k-1)][k-1]); } int Query(int x,int y){ if(x==y) return n-x+1; int l=rank[x],r=rank[y]; if(l>r) swap(l,r); l++; int t=lg2[r-l+1]; return min(st[l][t],st[r-(1<<t)+1][t]); }}S,P;int f[N],g[N]; int main(){ freopen("1.in","r",stdin); freopen("1.out","w",stdout); scanf("%d",&t); for(int i=1;i<=30000;i++) lg2[i]=lg2[i-1]+((1<<lg2[i-1]+1)==i); while(t--){ scanf("%s",a+1); n=strlen(a+1); t1[n+1]=t2[n+1]=0; S.build(); S.GetHeight(); S.Pre(); reverse(a+1,a+1+n); P.build(); P.GetHeight(); P.Pre(); for(int i=1;i<=n;i++) f[i]=g[i]=0; for(int L=1;L+L<=n;L++) for(int lst=1,i=L+1;i<=n;lst=i,i+=L){ int left=min(P.Query(n-lst+1,n-i+1),L),right=min(S.Query(lst,i),L),d=left+right-L; if(d<0) continue; f[i+right-d]++; f[i+right]--; g[lst-left+d+1]--; g[lst-left+1]++; } for(int i=1;i<=n;i++) f[i]+=f[i-1],g[i]+=g[i-1]; ll ans=0; for(int i=1;i<n;i++) ans+=1LL*f[i]*g[i+1]; printf("%lld\n",ans); } return 0;}
阅读全文
0 0
- [BZOJ4650][NOI2016]优秀的拆分-后缀数组
- [后缀数组] BZOJ4650: [Noi2016] 优秀的拆分
- bzoj4650: [Noi2016]优秀的拆分
- 【后缀数组】[NOI2016]优秀的拆分
- NOI2016 优秀的拆分 后缀数组
- NOI2016 优秀的拆分 后缀数组
- NOI2016优秀的拆分 后缀数组
- [BZOJ4650][NOI2016]优秀的拆分 各数据点解法
- 【NOI2016】优秀的拆分
- [后缀数组 枚举 字符串分段] BZOJ 4650 [Noi2016]优秀的拆分
- 4650: [Noi2016]优秀的拆分
- NOI 2016 优秀的拆分 后缀数组
- bzoj 4650: [Noi2016]优秀的拆分
- BZOJ 4650([Noi2016]优秀的拆分-SA)
- 【NOI2016】优秀的拆分(95分)
- [UOJ P219][NOI2016]优秀的拆分[95]
- Noi2016 D1 T1 优秀的拆分 90做法
- BZOJ 4650: [Noi2016]优秀的拆分 哈希+分块
- 手机号发送验证码
- R语言之饼状图
- Android锁屏勒索病毒分析(4)秒抢红包
- SVM算法
- opencv3/C++基于颜色的目标跟踪
- [后缀数组] BZOJ4650: [Noi2016] 优秀的拆分
- Android 封装工具类之文件缓存
- 字符编码简介:ASCII,Unicode,UTF-8,GB2312及Unicode和UTF-8如何转化
- TortoiseSVN报错:“Previous operation has not finished; run 'clean up' if it was interrupted“ 的解决方法
- 欧几里得算法求解乘法逆元——Python
- cocos2dx :多场景切换过程中的生命周期变化
- JavaScript更新日志(5)
- springboot+Rabit实战二:(Rabbit MQ web 界面管理)
- java--集合案例