回文自动机模板
#include<bits/stdc++.h> using namespace std; struct PAM{ #define ll long long #define LL long long static const int maxn=3e5+10; static const int num=27; char ss[maxn]; int c=0; int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num]; int last,tot; //LL ans; void inint(){ c=0; last=0; tot=0; fail[0]=fail[1]=1; len[0]=0; len[1]=-1; tot++; } int get_fail(int p,int pos){ while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p]; return p; } void add(int x,int pos){ ss[c]='a'+x; c++; int p=get_fail(last,pos); if(!ch[p][x]){ len[++tot]=len[p]+2; fail[tot]=ch[get_fail(fail[p],pos)][x]; ch[p][x]=tot; //ans++; } cnt[last=ch[p][x]]++; } void clear(){ for(int i=0;i<=tot;i++){ fail[i]=0; len[i]=0; cnt[i]=0; for(int j=0;j<num;j++) ch[i][j]=0; } last=tot=ans=0; } }pam; const int maxn=1e5+10; char ss[maxn]; int main(){ }
回文自动机 本质不同回文串个数 tot-1;
#include<bits/stdc++.h> #define ll long long #define LL long long using namespace std; const int maxn=2e5+10; const int num=26; char ss[maxn]; int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num]; struct PAM{ int last,tot; ll ans; void inint(){ last=0; tot=0; fail[0]=fail[1]=1; len[0]=0; len[1]=-1; tot++; } int get_fail(int p,int pos){ while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p]; return p; } void add(int x,int pos){ int p=get_fail(last,pos); if(!ch[p][x]){ len[++tot]=len[p]+2; fail[tot]=ch[get_fail(fail[p],pos)][x]; ch[p][x]=tot; } cnt[last=ch[p][x]]++; } void count(){ // bu zhi bu tong hui wen ge shu for(int i=tot;i>=0;i--){ cnt[fail[i]]+=cnt[i]; cnt[fail[i]]%=51123987; } } ll count_tot(){ ll w=0; count(); for(int i=2;i<=tot;i++) w+=cnt[i]; return w; } void clear(){ for(int i=0;i<=tot;i++){ fail[i]=0; len[i]=0; cnt[i]=0; for(int j=0;j<num;j++) ch[i][j]=0; } last=tot=ans=0; } }pam; int main(){ //int x; scanf("%d",&x); scanf("%s",ss); int l=strlen(ss); pam.inint(); for(int i=0;i<l;i++) { pam.add(ss[i]-'a',i); if(i!=0) printf(" "); printf("%d",pam.tot-1); } }
回文自动机 字符串l-r 区间本质不同回文串个数
#include<bits/stdc++.h> #define ll long long #define LL long long using namespace std; const int maxn=1010; struct PAM{ static const int maxn=1e3+10; static const int num=26; char ss[maxn]; int c=0; int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num]; int last,tot; ll ans; void inint(){ last=0; tot=0; c=0; fail[0]=fail[1]=1; len[0]=0; len[1]=-1; tot++; } int get_fail(int p,int pos){ while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p]; return p; } void add(int x,int pos){ ss[c++]=x+'a'; int p=get_fail(last,pos); if(!ch[p][x]){ len[++tot]=len[p]+2; fail[tot]=ch[get_fail(fail[p],pos)][x]; ch[p][x]=tot; } cnt[last=ch[p][x]]++; } void clear(){ for(int i=0;i<=tot;i++){ fail[i]=0; len[i]=0; cnt[i]=0; for(int j=0;j<num;j++) ch[i][j]=0; } last=tot=ans=0; c=0; } }pam; char ss[maxn]; int a[maxn][maxn]; int main(){ int T; scanf("%d",&T); while(T--){ scanf("%s",ss); int q; scanf("%d",&q); int n=strlen(ss); for(int i=0;i<n;i++){ pam.clear(); pam.inint(); for(int j=i;j<n;j++){ pam.add(ss[j]-'a',j-i); a[i][j]=pam.tot-1; } } while(q--){ int l,r; scanf("%d %d",&l,&r); printf("%d\n",a[l-1][r-1]); } } }
回文自动机 回文串权值问题
#include<bits/stdc++.h> #define ll long long #define LL long long using namespace std; const int maxn=1010000; struct PAM{ static const int maxn=3e5+10; static const int num=26; char ss[maxn]; int c=0; int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num]; int last,tot; ll ans=0; void inint(){ last=0; tot=0; c=0; ans=0; fail[0]=fail[1]=1; len[0]=0; len[1]=-1; tot++; } int get_fail(int p,int pos){ while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p]; return p; } void add(int x,int pos){ ss[c++]=x+'a'; int p=get_fail(last,pos); if(!ch[p][x]){ len[++tot]=len[p]+2; fail[tot]=ch[get_fail(fail[p],pos)][x]; ch[p][x]=tot; } cnt[last=ch[p][x]]++; } void dfs(int x){ for(int i=0;i<num;i++){ if(ch[x][i]){ int w=ch[x][i]; //cout<<w<<" "<<cnt[w]<<" "<<len[w]<<endl; ans=max(1ll*cnt[w]*len[w],ans); dfs(w); } } } ll slove(){ for(int i=tot;i>=0;i--) cnt[fail[i]]+=cnt[i]; dfs(1); dfs(0); return ans; } void clear(){ for(int i=0;i<=tot;i++){ fail[i]=0; len[i]=0; cnt[i]=0; for(int j=0;j<num;j++) ch[i][j]=0; } last=tot=ans=0; c=0; } }pam; char ss[maxn]; int a[maxn][maxn]; int main(){ scanf("%s",ss); pam.inint(); int n=strlen(ss); for(int i=0;i<n;i++){ pam.add(ss[i]-'a',i); } printf("%lld\n",pam.slove()); }
hdu 5394 回文自动机上删点 加点操作 回文自动机上记忆化搜索
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<vector> #include<stdio.h> #include<math.h> using namespace std; struct PAM{ #define ll long long #define LL long long static const int maxn=2e6+10; static const int num=27; char ss[maxn]; int relast[maxn]; int retot[maxn]; ll sum[maxn]; bool check[maxn]; int c=0; int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num]; int last,tot; void inint(){ c=0; last=0; tot=0; fail[0]=fail[1]=1; len[0]=0; len[1]=-1; tot++; } int get_fail(int p,int pos){ while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p]; return p; } void add(int x,int pos){ ss[c]='a'+x; c++; relast[pos]=last;// retot[pos]=tot;// int p=get_fail(last,pos); if(!ch[p][x]){ check[pos]=1;// len[++tot]=len[p]+2; fail[tot]=ch[get_fail(fail[p],pos)][x]; ch[p][x]=tot; } cnt[last=ch[p][x]]++; } void re(int x,int pos){ c--; last=relast[pos]; tot=retot[pos]; int p=get_fail(last,pos); if(check[pos]==1){ check[pos]=0; len[++tot]=0; fail[tot]=0; ch[p][x]=0; sum[tot]=0; } cnt[last=ch[p][x]]--; last=relast[pos]; tot=retot[pos]; relast[pos]=0; retot[pos]=0; } ll dfs(int x){ if(x==0 || x==1) return 0; if(sum[x]!=0) return sum[x]; return sum[x]=dfs(fail[x])+len[x]; } ll work(){ return dfs(last); } }pam; #define ll long long const int maxn=2e6+10; //char ss[maxn]; ll ans=0; vector<pair<int,char> > vs[maxn]; void dfs(int x,int tot){ for(int i=0;i<vs[x].size();i++){ pam.add(vs[x][i].second,tot); ans+=pam.work(); dfs(vs[x][i].first,tot+1); pam.re(vs[x][i].second,tot); } } struct FastIO { static const int S = 4e6; int wpos; char wbuf[S]; FastIO() : wpos(0) {} inline int xchar() { static char buf[S]; static int len = 0, pos = 0; if (pos == len) pos = 0, len = fread(buf, 1, S, stdin); if (pos == len) exit(0); return buf[pos++]; } inline int xuint() { int c = xchar(), x = 0; while (c <= 32) c = xchar(); for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0'; return x; } inline int xint() { int s = 1, c = xchar(), x = 0; while (c <= 32) c = xchar(); if (c == '-') s = -1, c = xchar(); for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0'; return x * s; } inline void xstring(char *s) { int c = xchar(); while (c <= 32) c = xchar(); for (; c > 32; c = xchar()) * s++ = c; *s = 0; } inline void wchar(int x) { if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0; wbuf[wpos++] = x; } inline void wint(int x) { if (x < 0) wchar('-'), x = -x; char s[24]; int n = 0; while (x || !n) s[n++] = '0' + x % 10, x /= 10; while (n--) wchar(s[n]); wchar('\n'); } inline void wstring(const char *s) { while (*s) wchar(*s++); } ~FastIO() { if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0; } } io; int main(){ int T; T=io.xint(); //cin>>T; while(T--){ pam.inint(); ans=0; int n; n=io.xint(); //cin>>n; for(int i=1;i<=n;i++){ char x; int y; x=io.xchar(); y=io.xint(); //cin>>x>>y; vs[y].push_back({i,x}); } dfs(0,0); printf("%lld\n",ans); for(int i=0;i<=n;i++) vs[i].clear(); // pam.clear(); } }
洛谷 最长双回文串
#include<bits/stdc++.h> using namespace std; struct PAM{ #define ll long long #define LL long long static const int maxn=3e5+10; static const int num=27; char ss[maxn]; int c=0; int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num]; int last,tot; LL ans; void inint(){ c=0; last=0; tot=0; fail[0]=fail[1]=1; len[0]=0; len[1]=-1; tot++; } int get_fail(int p,int pos){ while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p]; return p; } void add(int x,int pos){ ss[c]='a'+x; c++; int p=get_fail(last,pos); if(!ch[p][x]){ len[++tot]=len[p]+2; fail[tot]=ch[get_fail(fail[p],pos)][x]; ch[p][x]=tot; ans++; } cnt[last=ch[p][x]]++; } int work(){ return len[last]; } void clear(){ for(int i=0;i<=tot;i++){ fail[i]=0; len[i]=0; cnt[i]=0; for(int j=0;j<num;j++) ch[i][j]=0; } last=tot=ans=0; } }pam; const int maxn=2e5+10; char ss[maxn]; int ans[maxn]; int main(){ scanf("%s",ss); int l=strlen(ss); pam.inint(); for(int i=0;i<l;i++){ pam.add(ss[i],i); ans[i]+=pam.work(); } pam.clear(); pam.inint(); for(int i=l-1;i>=0;i--){ pam.add(ss[i],l-1-i); if(i-1>=0) ans[i-1]+=pam.work(); } int x=0; for(int i=1;i<l-1;i++){ x=max(ans[i],x); } printf("%d\n",x); }
洛谷 拉拉队排练
#include<bits/stdc++.h> using namespace std; int numm[2000005]; struct PAM{ #define ll long long #define LL long long static const int maxn=2e6+10; static const int num=27; char ss[maxn]; int c=0; int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num]; int last,tot; LL ans; void inint(){ c=0; last=0; tot=0; fail[0]=fail[1]=1; len[0]=0; len[1]=-1; tot++; } int get_fail(int p,int pos){ while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p]; return p; } void add(int x,int pos){ ss[c]='a'+x; c++; int p=get_fail(last,pos); if(!ch[p][x]){ len[++tot]=len[p]+2; fail[tot]=ch[get_fail(fail[p],pos)][x]; ch[p][x]=tot; ans++; } cnt[last=ch[p][x]]++; } void count(){ for(int i=tot;i>=2;i--){ cnt[fail[i]]+=cnt[i]; if(len[i]%2==1){ numm[len[i]]+=cnt[i]; } } } void clear(){ for(int i=0;i<=tot;i++){ fail[i]=0; len[i]=0; cnt[i]=0; for(int j=0;j<num;j++) ch[i][j]=0; } last=tot=ans=0; } }pam; const int maxn=2e6+10; const int mod=19930726; #define ll long long char ss[maxn]; int quick(int x,int n){ int ans=1; while(n){ if(n&1) ans=1ll*ans*x%mod; x=1ll*x*x%mod; n=n/2; } return ans; } int main(){ ll n,k; scanf("%lld %lld",&n,&k); scanf("%s",ss); pam.inint(); for(int i=0;i<n;i++)pam.add(ss[i],i); pam.count(); ll ans=1; ll w=0; for(int i=n;i>=1;i--){ //cout<<numm[i]<<endl; if(i%2==1) w+=numm[i]; if(i%2==1 && k){ if(numm[i]<=k){ ans=1ll*ans*quick(i,numm[i])%mod; k-=numm[i]; } else { ans=1ll*ans*quick(i,k)%mod; k=0; } } } if(w<k) printf("-1\n"); else printf("%lld\n",ans); }
hdu 5157
#include<bits/stdc++.h> using namespace std; struct PAM{ #define ll long long #define LL long long static const int maxn=2e5+10; static const int num=27; char ss[maxn]; int c=0; int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num]; int last,tot; int sum[maxn]; //LL ans; void inint(){ c=0; last=0; tot=0; fail[0]=fail[1]=1; len[0]=0; len[1]=-1; tot++; } int get_fail(int p,int pos){ while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p]; return p; } void add(int x,int pos){ ss[c]='a'+x; c++; int p=get_fail(last,pos); if(!ch[p][x]){ len[++tot]=len[p]+2; fail[tot]=ch[get_fail(fail[p],pos)][x]; ch[p][x]=tot; //ans++; } cnt[last=ch[p][x]]++; } int dfs(int x){ if(x==0 || x==1) return 0; if(sum[x]!=0) return sum[x]; return sum[x]=dfs(fail[x])+1; } int work(){ return dfs(last); } void clear(){ for(int i=0;i<=tot;i++){ fail[i]=0; len[i]=0; cnt[i]=0; sum[i]=0; for(int j=0;j<num;j++) ch[i][j]=0; } last=tot=0; } }pam; #define ll long long const int maxn=1e5+10; char ss[maxn]; ll a[maxn]; ll b[maxn]; ll sumb[maxn]; int main(){ while(scanf("%s",ss)!=EOF){ int l=strlen(ss); pam.inint(); for(int i=0;i<l;i++){ pam.add(ss[i]-'a',i); a[i]=pam.work(); } pam.clear(); pam.inint(); for(int i=l-1;i>=0;i--){ pam.add(ss[i]-'a',l-1-i); b[i]=pam.work(); } for(int i=l-1;i>=0;i--){ sumb[i]=sumb[i+1]+b[i]; } ll ans=0; for(int i=0;i<l;i++){ ans+=1ll*a[i]*sumb[i+1]; } printf("%lld\n",ans); for(int i=0;i<=l;i++) a[i]=b[i]=sumb[i]=0; pam.clear(); } }
hdu 6599 回文自动机 哈希 回文串 (l-r)回文 (l-(l+r)/2)回文)
#include<bits/stdc++.h> #define ll long long #define LL long long using namespace std; const int maxn=3e5+10; const int mod=1e9+7; const int h1=222333; char ss[maxn]; int a[maxn]; int ha[maxn]; int hb[maxn]; int hh[maxn]; struct PAM{ #define ll long long #define LL long long static const int maxn=3e5+10; static const int num=27; int fail[maxn],cnt[maxn],len[maxn],ch[maxn][num]; int last,tot; LL ans; void inint(){ last=0; tot=0; fail[0]=fail[1]=1; len[0]=0; len[1]=-1; tot++; } int get_fail(int p,int pos){ while(ss[pos-len[p]-1]!=ss[pos]) p=fail[p]; return p; } void add(int x,int pos){ int p=get_fail(last,pos); if(!ch[p][x]){ len[++tot]=len[p]+2; fail[tot]=ch[get_fail(fail[p],pos)][x]; ch[p][x]=tot; ans++; } cnt[last=ch[p][x]]++; } void count(){ // bu zhi bu tong hui wen ge shu for(int i=tot;i>=0;i--){ cnt[fail[i]]+=cnt[i]; } } void dfs(int x,int pos){ for(int i=0;i<num;i++){ if(ch[x][i]){ if(pos==0) ha[pos]=(1ll*i)%mod; else ha[pos]=(1ll*ha[pos-1]*h1+i)%mod; if(pos==0) hb[pos]=(1ll*i*hh[pos])%mod; else hb[pos]=(1ll*i*hh[pos]+hb[pos-1])%mod; int k=ch[x][i]; if(ha[pos]==hb[pos]){ a[len[k]]+=cnt[k]; } dfs(k,pos+1); } } } void work(){ dfs(0,0); dfs(1,0); } void clear(){ for(int i=0;i<=tot;i++){ fail[i]=0; len[i]=0; cnt[i]=0; for(int j=0;j<num;j++) ch[i][j]=0; } last=tot=ans=0; } }pam; int main(){ hh[0]=1; for(int i=1;i<maxn;i++) hh[i]=1ll*hh[i-1]*h1%mod; while(~scanf("%s",ss)){ int l=strlen(ss); pam.inint(); //cout<<l<<endl; for(int i=0;i<l;i++) pam.add(ss[i]-'a',i); pam.count(); pam.work(); for(int i=1;i<=l;i++){ if(i!=1) printf(" "); printf("%d",a[i]); a[i]=0; }printf("\n"); pam.clear(); } }
后缀自动机
#include<bits/stdc++.h> #define ll long long using namespace std; struct SAM // /* https://www.cnblogs.com/weeping/p/7516063.html */ { static const int MAXN = 50000<<1;//大小为字符串长度两倍 static const int LetterSize = 300; int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN]; int num[MAXN]; void init( void) { last = tot = 1; len[1] = 0; memset( ch[1], 0, sizeof ch[1]); } void add( int x) { int p = last, np = last = ++tot; num[tot]=1; len[np] = len[p] + 1;//cnt[last] = 1; memset( ch[np], 0, sizeof ch[np]); while( p && !ch[p][x]) ch[p][x] = np, p = fa[p]; if( p == 0) fa[np] = 1; else { int q = ch[p][x]; if( len[q] == len[p] + 1) fa[np] = q; else { int nq = ++tot; memcpy( ch[nq], ch[q], sizeof ch[q]); len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq; while( p && ch[p][x] == q) ch[p][x] = nq, p = fa[p]; } } } void use(){ ll ans=0; for(int i=2;i<=tot;i++) { ans+=len[i]-len[fa[i]]; } printf("%lld\n",ans); } }sam; const int maxn=1e6+10; char ss[maxn]; int main(){ int T; scanf("%d",&T); while(T--){ scanf("%s",ss); int l=strlen(ss); sam.init(); for(int i=0;i<l;i++) sam.add(ss[i]-'a'); sam.use(); } }
本质不同字符串个数(模板题)New Distinct Substrings SPOJ - SUBST1
#include<bits/stdc++.h> #define ll long long using namespace std; struct SAM{ static const int MAXN = 50000<<1;//大小为字符串长度两倍 static const int LetterSize = 300; int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN]; int num[MAXN]; void init( void) { last = tot = 1; len[1] = 0; memset( ch[1], 0, sizeof ch[1]); } void add( int x) { int p = last, np = last = ++tot; num[tot]=1; len[np] = len[p] + 1;//cnt[last] = 1; memset( ch[np], 0, sizeof ch[np]); while( p && !ch[p][x]) ch[p][x] = np, p = fa[p]; if( p == 0) fa[np] = 1; else { int q = ch[p][x]; if( len[q] == len[p] + 1) fa[np] = q; else { int nq = ++tot; memcpy( ch[nq], ch[q], sizeof ch[q]); len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq; while( p && ch[p][x] == q) ch[p][x] = nq, p = fa[p]; } } } void use(){ ll ans=0; for(int i=2;i<=tot;i++) { ans+=len[i]-len[fa[i]]; } printf("%lld\n",ans); } }sam; const int maxn=1e6+10; char ss[maxn]; int main(){ int T; scanf("%d",&T); while(T--){ scanf("%s",ss); int l=strlen(ss); sam.init(); for(int i=0;i<l;i++) sam.add(ss[i]-'a'); sam.use(); } }
两字符串的最长相同字串
#include<bits/stdc++.h> #define ll long long using namespace std; struct SAM{ static const int MAXN = 250010<<1;//大小为字符串长度两倍 static const int LetterSize = 300; int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN]; int num[MAXN]; void init( void){ last = tot = 1; len[1] = 0; len[0]=0; memset( ch[1], 0, sizeof ch[1]); } void add( int x) { int p = last, np = last = ++tot; num[tot]=1; len[np] = len[p] + 1; memset(ch[np],0,sizeof ch[np]); while(p&&!ch[p][x]) ch[p][x] = np, p = fa[p]; if( p == 0) fa[np] = 1; else{ int q = ch[p][x]; if( len[q] == len[p] + 1) fa[np] = q; else{ int nq = ++tot; memcpy( ch[nq], ch[q], sizeof ch[q]); len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq; while( p && ch[p][x] == q) ch[p][x] = nq, p = fa[p]; } } } }sam; const int maxn=1e6+10; char ss[maxn]; char tt[maxn]; int main(){ scanf("%s",ss); int l=strlen(ss); sam.init(); for(int i=0;i<l;i++) sam.add(ss[i]-'a'); scanf("%s",tt); int r=strlen(tt); int ans=0; int p=1; int d=0; for(int i=0;i<r;i++){ if(sam.ch[p][tt[i]-'a']){ p=sam.ch[p][tt[i]-'a']; d++; } else { while(sam.ch[p][tt[i]-'a']==0 && p!=1){ p=sam.fa[p]; d=sam.len[p]; } if(sam.ch[p][tt[i]-'a']) { p=sam.ch[p][tt[i]-'a']; d++;} } //cout<<d<<endl; ans=max(ans,d); } printf("%d\n",ans); }
hdu 6583 后缀自动机 + dp http://acm.hdu.edu.cn/showproblem.php?pid=6583
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> #define ll long long #define LL long long using namespace std; struct SAM { static const int MAXN = 200010<<1;//大小为字符串长度两倍 static const int LetterSize = 26; int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN]; int num[MAXN]; void init( void) { last = tot = 1; len[1] = 0; fa[1]=0; memset( ch, 0, sizeof(ch)); memset( fa,0,sizeof(fa)); memset( len,0,sizeof(len)); } void add( int x) { int p = last, np = last = ++tot; num[tot]=1; len[np] = len[p] + 1; memset( ch[np], 0, sizeof ch[np]); while( p && !ch[p][x]) ch[p][x] = np, p = fa[p]; if( p == 0) fa[np] = 1; else { int q = ch[p][x]; if( len[q] == len[p] + 1) fa[np] = q; else { int nq = ++tot; memcpy( ch[nq], ch[q], sizeof ch[q]); len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq; while( p && ch[p][x] == q) ch[p][x] = nq, p = fa[p]; } } } }sam; const int maxn=2e5+10; char ss[maxn]; ll dp[maxn]; int main(){ while(~scanf("%s",ss)){ int p,q; scanf("%d %d",&p,&q); int l=strlen(ss); sam.init(); int now=1; int j=0; for(int i=0;i<l;i++) dp[i]=1e18; for(int i=0;i<l;i++){ if(i==0) dp[i]=p; else dp[i]=min(dp[i],dp[i-1]+p); int x=ss[i]-'a'; while( (!sam.ch[now][x] || i-j+1>=j+1) &&j<=i ){ sam.add(ss[j++]-'a'); while(now && sam.len[sam.fa[now]]>=i-j) now=sam.fa[now]; if(!now) now=1; } now=sam.ch[now][x]; while(now && sam.len[sam.fa[now]]>=i-j+1) now=sam.fa[now]; if(!now) now=1; if(i>=j){ dp[i]=min(dp[i],dp[j-1]+q); } // cout<<dp[i]<<" "<<i<<" "<<j<<endl; } printf("%lld\n",dp[l-1]); } }