原文链接https://www.cnblogs.com/zhouzhendong/p/HDU5470.html
题意
题解
太晚了,先鸽一鸽。
代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N=100005; int T,n,Case=0; int R[N],c[26],A,B; int Time[N<<1],tax[N],id[N<<1]; char s[N]; LL dp[N],v[N],q[N],head,tail; struct SAM{ int Next[26],fa,Max; }t[N<<1]; int size; void init(){ memset(t,0,sizeof t); memset(Time,63,sizeof Time); size=1,t[0].Max=-1; for (int i=0;i<26;i++) t[0].Next[i]=1; } int extend(int p,int c){ if (t[p].Next[c]&&t[p].Max+1==t[t[p].Next[c]].Max) return t[p].Next[c]; int np=++size,q,nq; t[np].Max=t[p].Max+1; for (;!t[p].Next[c];p=t[p].fa) t[p].Next[c]=np; q=t[p].Next[c]; if (t[p].Max+1==t[q].Max) t[np].fa=q; else { nq=++size; t[nq]=t[q],t[nq].Max=t[p].Max+1; t[np].fa=t[q].fa=nq; for (;t[p].Next[c]==q;p=t[p].fa) t[p].Next[c]=nq; } return np; } void Get_Time(){ memset(tax,0,sizeof tax); for (int i=1;i<=size;i++) tax[t[i].Max]++; for (int i=1;i<=n;i++) tax[i]+=tax[i-1]; for (int i=1;i<=size;i++) id[tax[t[i].Max]--]=i; for (int i=size;i>1;i--) Time[t[id[i]].fa]=min(Time[t[id[i]].fa],Time[id[i]]); } int main(){ scanf("%d",&T); while (T--){ scanf("%s",s+1); n=strlen(s+1); init(); for (int i=1,p=1;i<=n;i++) Time[p=extend(p,s[i]-'a')]=i; Get_Time(); for (int i=0;i<26;i++) scanf("%d",&c[i]); scanf("%d%d",&A,&B); for (int i=1,j=0,p=1,len=0;i<=n;i++){ while (1){ int Next=t[p].Next[s[j+1]-'a']; while (!(Next&&Time[Next]<i)&&j-t[t[p].fa].Max<i) p=t[p].fa,len=t[p].Max,Next=t[p].Next[s[j+1]-'a']; if (Next&&Time[Next]<i) j++,p=Next; else break; } R[i]=j; } head=1,tail=0; memset(q,0,sizeof q); dp[0]=0; for (int i=1;i<=n;i++){ dp[i]=dp[i-1]+c[s[i]-'a']; while (head<=tail&&R[q[head]+1]<i) head++; if (head<=tail) dp[i]=min(dp[i],v[q[head]]+1LL*A*i+B*2); v[i]=dp[i]-1LL*A*i; if (R[i+1]>i){ while (head<=tail&&v[i]<=v[q[tail]]) tail--; q[++tail]=i; } } printf("Case #%d: %lld\n",++Case,dp[n]); } return 0; }