tjut 3948
来源:互联网 发布:iphone主题软件下载 编辑:程序博客网 时间:2024/06/15 13:53
include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#include<cmath>#include<vector>using namespace std;typedef long long LL;const int N=200000+10;char s[N],s1[N];struct SuffixArray{ int a1[N],a2[N],c[N],SA[N],sa[N],*rank,*x,*y; int n,height[N],m; void sort(){ for (int i=0;i<m;i++) c[i]=0; for (int i=0;i<n;i++) c[x[i]]++; for (int i=0;i<m;i++) c[i+1]+=c[i]; for (int i=n-1;i>=0;i--) SA[ --c[x[sa[i]]] ] = sa[i]; } void build_sa(char *s){ n=strlen(s); m=256; x=a1; y=a2; x[n]=y[n]=-1; for (int i=0;i<n;i++) x[i]=s[i],sa[i]=i; sort(); for (int k=1;k<=n;k<<=1){ int p=0; for (int i=n-k;i<n;i++) sa[p++]=i; for (int i=0;i<n;i++) if (SA[i]>=k) sa[p++]=SA[i]-k; sort(); p=0; swap(x,y); x[SA[0]]=0; for (int i=1;i<n;i++){ if ( y[ SA[i-1] ]!=y[ SA[i] ] || y[ SA[i-1]+k ]!=y[ SA[i]+k ] ) p++; x[SA[i]]=p; } if (p+1==n) break; m=p+1; } rank=x; getHeight(s); } void getHeight(char *s){ int k=0; for (int i=0;i<n;i++){ if (k) k--; if (rank[i]==0) continue; int j=SA[ rank[i]-1 ]; while (i+k<n && j+k<n && s[i+k]==s[j+k]) k++; height[rank[i]]=k; } height[n]=0; }}H;int lc[N*2];int lx[N],ly[N];void init(char *s1){ int c=0; int n=strlen(s1); s[c++]='$';s[c++]='#'; for (int i=0;s1[i];i++){ s[c++]=s1[i]; s[c++]='#'; }s[c]='\0'; lc[0]=1;lc[1]=1; int k=1; for (int i=2;i<c;i++){ int p=k+lc[k]-1; if (i>=p){ int j=0; while (i-j>=0 && i+j<c && s[i-j]==s[i+j]) j++; lc[i]=j; k=i; }else { int j=2*k-i; if (i+lc[j]-1<p) lc[i]=lc[j]; else { int d=p-i+1; while (i-d>=0 && i+d<c && s[i-d]==s[i+d]) d++; lc[i]=d; k=i; } } }}void solve(){ int n=strlen(s); int ret=lc[H.SA[0]]; int tmp=lc[H.SA[0]];// cout<<s<<endl;// cout<<H.SA[0]<<" "<<lc[H.SA[0]]<<" "<<s+H.SA[0]<<endl; for (int i=1;i<n;i++){ int t=H.SA[i];// cout<<H.SA[i]<<" "<<lc[H.SA[i]]<<" "<<s+H.SA[i]<<endl; ret+=max(0,(lc[t]-min(H.height[i],tmp))/2);//tmp表示以字符s[H.SA[i-1]]为中心已经被统计过的回文串的个数 if (lc[t]>=tmp) tmp=lc[t]; else { tmp=min(tmp,H.height[i]);//从上一个传递到当前; if (lc[t]>tmp) tmp=lc[t];//如果该后缀本身的回文个数更多久更新; } } printf("%d\n",ret-1);}int main(){ int T,cas=0; scanf("%d",&T); while (T--){ scanf("%s",s1); init(s1); H.build_sa(s); printf("Case #%d: ",++cas); solve(); } return 0;}
0 0
- tjut 3948
- tjut 5289
- tjut 5288
- tjut 5294
- tjut 2586
- tjut 5296
- tjut 5297
- tjut 5299
- tjut 5384
- tjut 5387
- tjut 5386
- tjut 5381
- tjut 5400
- tjut 5399
- tjut 5396
- tjut 5398
- tjut 5412
- tjut 5410
- 关于Single Number II的一些讨论
- c++ 模板类 声明和定义都放在.h文件的原因
- windows下文件共享以及通过网线在两台Windows电脑之间传数据
- Task schedule
- Linux--网络基础
- tjut 3948
- 10+ 最佳的 Node.js 教程和实例
- LeetCode-TwoSum
- #pragma once与#ifndef两种防止头文件二次编译的区别
- C语言练习
- 字符串按照多个字符分割
- 关于myBatis
- 《PCL点云库学习&VS2010(X64)》Part 19 PCL1.72(VTK6.2.0)PCL程序计时
- mybatis:方法需要传入多个参数时,报错:Caused by: org.apache.ibatis.binding.BindingException: Parameter 'p_v_id' not