Best Reward HDU
阿新 • • 發佈:2018-12-14
馬拉車存模板 求出每個迴文中心的迴文半徑 列舉端點 看兩邊是為迴文即可
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=1e6+10; int book[maxn],pre[maxn]; char tmp[maxn],ch[maxn]; int l; int solve(char *ch,int l) { int i,p,r,res; memset(book,0,sizeof(book)); p=0,r=0,res=0; for(i=0;i<l;i++) { if(i<r) book[i]=min(book[2*p-i],r-i); else book[i]=1; while(0<=i-book[i]&&i+book[i]<l&&ch[i-book[i]]==ch[i+book[i]]) book[i]++; res=max(res,book[i]); if(r<=i+book[i]) { r=i+book[i]; p=i; } } return res; } int main() { int val[50]; int t,i,j,ans,sum; scanf("%d",&t); while(t--) { for(i=0;i<26;i++) scanf("%d",&val[i]); scanf("%s",tmp); l=strlen(tmp); j=0; for(i=0;i<l;i++) ch[j++]='*',ch[j++]=tmp[i]; ch[j++]='*',ch[j]='\0'; l=j; for(i=0;i<l/2;i++) { pre[i]=val[tmp[i]-'a']; if(i>0) pre[i]+=pre[i-1]; } solve(ch,l); ans=0; for(i=0;i+1<l/2;i++) { sum=0; if(book[i+1]-1==i+1) sum+=pre[i]; if(book[i+1+l/2]-1==l/2-(i+1)) sum+=pre[l/2-1]-pre[i]; ans=max(ans,sum); } printf("%d\n",ans); } return 0; }