题目大意:
给个字符串S,要把S分成两段T1,T2,每个字母都有一个对应的价值,如果T1,T2是回文串(从左往右或者从右往左读,都一样),那么他们就会有一个价值,这个价值是这个串的所有字母价值之和,如果不是回文串,那么这串价值就为0。问最多能获得多少价值?
对于我们只需要枚举扫描一遍extend数组,扫描到的当前位置之前为前半部分T1,
然后用根据extend数组可以判断T1是否是回文。那后半部分T2呢? 刚才是用S去匹配T,
如果要求后缀,只需要用T去匹配S,再得到一个数组extend2即可,根据这个extend2判断后半部分T2是否是回文。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x3f3f3f3f; 11 const double eps=1e-5; 12 #define cl(a) memset(a,0,sizeof(a)) 13 #define ts printf("*****\n"); 14 const int MAXN=500005; 15 int n,m,tt; 16 char s1[MAXN],s2[MAXN]; 17 int v[29],sum[MAXN]; 18 void pre_EKMP(char x[],int m,int nextt[]) 19 { 20 nextt[0]=m; 21 int j=0; 22 while(j+1<m && x[j]==x[j+1])j++; 23 nextt[1]=j; 24 int k=1; 25 for(int i=2;i<m;i++) 26 { 27 int p=nextt[k]+k-1; 28 int L=nextt[i-k]; 29 if(i+L<p+1)nextt[i]=L; 30 else 31 { 32 j=max(0,p-i+1); 33 while(i+j<m && x[i+j]==x[j])j++; 34 nextt[i]=j; 35 k=i; 36 } 37 } 38 } 39 void EKMP(char x[],int m,char y[],int n,int nextt[],int extend[]) 40 { 41 pre_EKMP(x,m,nextt); 42 int j=0; 43 while(j<n && j<m && x[j]==y[j])j++; 44 extend[0]=j; 45 int k=0; 46 for(int i=1;i<n;i++) 47 { 48 int p=extend[k]+k-1; 49 int L=nextt[i-k]; 50 if(i+L<p+1)extend[i]=L; 51 else 52 { 53 j=max(0,p-i+1); 54 while(i+j<n && j<m && y[i+j]==x[j])j++; 55 extend[i]=j; 56 k=i; 57 } 58 } 59 } 60 int nextt[MAXN],extend1[MAXN],extend2[MAXN]; 61 int main() 62 { 63 int i,j,k; 64 #ifndef ONLINE_JUDGE 65 freopen("1.in","r",stdin); 66 #endif 67 scanf("%d",&tt); 68 while(tt--) 69 { 70 for(i=0;i<26;i++) 71 { 72 scanf("%d",&v[i]); 73 } 74 scanf("%s",s1); 75 int len=strlen(s1); 76 for(i=0;i<len;i++) 77 { 78 sum[i+1]=v[s1[i]-‘a‘]+sum[i]; 79 } 80 strcpy(s2,s1); 81 strrev(s2); 82 EKMP(s2,len,s1,len,nextt,extend1); 83 EKMP(s1,len,s2,len,nextt,extend2); 84 int maxx=0; 85 for(i=1;i<len;i++) //枚举断点 86 { 87 int tot=0; 88 if(i+extend1[i]==len) //这里求的是断点后面的 89 { 90 tot+=sum[len]-sum[i]; 91 } 92 int ll=len-i; 93 if(ll+extend2[ll]==len) 94 { 95 tot+=sum[len]-sum[ll]; 96 } 97 maxx=max(maxx,tot); 98 } 99 printf("%d\n",maxx); 100 } 101 }
时间: 2024-12-16 11:59:19