提交时间:2024-06-23 18:55:14
运行 ID: 30352
#include<iostream> #include<cstring> #include<bitset> using namespace std; const int N=100100; #define int long long //998244853 233 //1000000009 133 template<int P,int B>class Hash{ int h[N],p[N]; public: Hash(){memset(h,0,sizeof(h));p[0]=1;for(int i=1;i<N;i++)p[i]=p[i-1]*B%P;} void init(char a[],int n){for(int i=1;i<=n;i++)h[i]=(h[i-1]*B+a[i])%P;} inline int get_hash(int l,int r){return ((h[r]-h[l-1]*p[r-l+1])%P+P)%P;} }; using pii=pair<int,int>; inline bool operator==(const pii&A,const pii&B){return A.first==B.first&&A.second==B.second;} class hash2{ Hash<998244853,233>h1; Hash<1000000009,133>h2; public: hash2():h1(),h2(){} void init(char a[],int n){h1.init(a,n),h2.init(a,n);} inline pii get_hash(int l,int r){return make_pair(h1.get_hash(l,r),h2.get_hash(l,r));} }h1,h2,h3; char A[N],B[N],C[N]; int n1,n2,n3; int f1[N],f2[N]; void init(){ scanf("%s\n%s\n%s",A+1,B+1,C+1); n1=strlen(A+1); n2=strlen(B+1); n3=strlen(C+1); h1.init(A,n1); h2.init(B,n2); h3.init(C,n3); f1[1]=0; for(int i=2;i<=n3;i++){ f1[i]=f1[i-1]; while(C[f1[i]+1]!=C[i]&&f1[i])f1[i]=f1[f1[i]]; if(C[f1[i]+1]==C[i])f1[i]++; } f2[n3]=n3+1; for(int i=n3-1;i;i--){ f2[i]=f2[i+1]; while(C[f2[i]-1]!=C[i]&&f2[i]<=n3)f2[i]=f2[f2[i]]; if(C[f2[i]-1]==C[i])f2[i]--; } } int pos1[N],cnt1[N],pos2[N],cnt2[N],cntb; bool tag1[N],tag2[N]; int g1[N],g2[N];//前后缀算到 i 时能匹配的次数 signed main(){ // freopen("string.in","r",stdin); // freopen("string.out","w",stdout); init(); int p=0; for(int i=1,cnt=0;i<=n1;i++){ while(p&&C[p+1]!=A[i])p=f1[p]; if(C[p+1]==A[i])p++; if(p==n3)cnt++,p=f1[p]; cnt1[i]=cnt; pos1[i]=p; } p=n3+1; for(int i=n1,cnt=0;i;i--){ while(p<=n3&&C[p-1]!=A[i])p=f2[p]; if(C[p-1]==A[i])p--; if(p==1)cnt++,p=f2[p]; cnt2[i]=cnt; pos2[i]=p; } p=0; for(int i=1;i<=n2;i++){ while(p&&C[p+1]!=B[i])p=f1[p]; if(C[p+1]==B[i])p++; if(p==n3)cntb++,p=f1[p]; } if(n2>n3){ for(int i=1;i<=n3;i++){ tag1[n3-i]=(h2.get_hash(1,i)==h3.get_hash(n3-i+1,n3)); tag2[i+1]=(h2.get_hash(n2-i+1,n2)==h3.get_hash(1,i)); } for(int i=1;i<=n3;i++)g1[i]=g1[f1[i]]+tag1[i]; for(int i=n3;i;i--)g2[i]=g2[f2[i]]+tag2[i]; int mx=0; for(int i=0;i<=n1;i++)mx=max(mx,cnt1[i]+cnt2[i+1]+cntb+g1[pos1[i]]+g2[pos2[i+1]]); cout<<mx<<' '; int tot=0; for(int i=0;i<=n1;i++)if(mx==cnt1[i]+cnt2[i+1]+cntb+g1[pos1[i]]+g2[pos2[i+1]])tot++; cout<<tot; return 0; } else{ for(int i=1;i<=n2;i++){ tag1[n3-i]=(h2.get_hash(1,i)==h3.get_hash(n3-i+1,n3)); tag2[i+1]=(h2.get_hash(n2-i+1,n2)==h3.get_hash(1,i)); } for(int i=1;i<=n3;i++)g1[i]=g1[f1[i]]+tag1[i]; for(int i=n3;i;i--)g2[i]=g2[f2[i]]+tag2[i]; int mx=0,tot=0; for(int i=0;i<=n1;i++){ int cnt=cnt1[i]+cnt2[i+1]+cntb+g1[pos1[i]]+g2[pos2[i+1]]; int p=pos1[i]; while(p+n2>=n3)p=f1[p]; while(p){ if(i+n3-p-n2<=n1&&h2.get_hash(1,n2)==h3.get_hash(p+1,p+n2)&&h3.get_hash(p+n2+1,n3)==h1.get_hash(i+1,i+n3-p-n2))cnt++; p=f1[p]; } // cerr<<pos1[i]<<' '<<cnt<<endl; if(cnt==mx)tot++; else if(cnt>mx)tot=1,mx=cnt; } cout<<mx<<' '<<tot; } return 0; }