1. 程式人生 > >拓展KMP求迴文串

拓展KMP求迴文串

題目:hdu3613;

題意:有26字母對應的價值,然後給出以個串,把它分成兩段字串,如果字串是迴文串,串的價值就是每個字元和,不是就為0。求最大價值。

部落格

分析:拓展KMP的應用求迴文字串。

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<string.h>
using namespace std;
const int max_=5e6+10;
int extend1[max_],extend2[max_],v[30
],w[max_], nex[max_]; void getnext(string str) { int a=0,p=0; int len=str.size(); nex[0]=len; for(int i=1;i<len;i++) { if(i>=p||i+nex[i-a]>=p) { if(i>=p) p=i; while(str[p-i]==str[p]&&p<len) p
++; nex[i]=p-i; a=i; } else nex[i]=nex[i-a]; } } void getextend(string str,string mo,int *ex) { int a=0,p=0; getnext(mo); int m=mo.size(); int len=str.size(); for(int i=0;i<len;i++) { if(i>=p||i+nex[i-a]>=p) {
if(i>=p) p=i; while(str[p]==mo[p-i]&&p<len&&p-i<m) p++; ex[i]=p-i; a=i; } else ex[i]=nex[i-a]; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int t; string S,T; scanf("%d",&t); while(t--) { int max_sum=-1e8; for(int i=0;i<26;i++) { scanf("%d",&v[i]); } cin>>S; int len=S.size(); for(int i=0;i<len;i++) { if(i==0) w[i]=v[S[i]-'a']; else w[i]=w[i-1]+v[S[i]-'a']; } T=S; reverse(T.begin(),T.end()); getextend(S,T,extend1); getextend(T,S,extend2); for(int i=1;i<len;i++) { int sum=0; if(i+extend1[i]==len) sum+=w[len-1]-w[i-1]; if(len-i+extend2[len-i]==len) sum+=w[i-1]; max_sum=max(max_sum,sum); } printf("%d\n",max_sum); } }