您的位置:首页 > 其它

HDU 3613 扩展KMP

2017-09-01 10:00 295 查看
暴力枚举大水题,判断回文,扩展KMP

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 500005;

int a[30];
char str[500005];
char str1[500005];
int s[500005];

int _next[maxn],_extend[maxn];
int next1[maxn],extend1[maxn];

void getnext(char *T) {
int a = 0;
int Tlen = strlen(T);
_next[0] = Tlen;
while(a<Tlen-1&&T[a]==T[a+1]) a++;
_next[1] = a;

a = 1;
for(int k=2; k < Tlen; k++) {
int p = a + _next[a] - 1,L = _next[k-a];
if((k-1)+L>=p) {
int j = (p-k+1) > 0 ? p - k + 1 : 0;
while(k+j<Tlen&&T[k+j]==T[j])
j++;
_next[k] = j;
a = k;
}
else _next[k] = L;
}
}

void getextend(char *S,char *T) {
int a = 0;
getnext(T);

int Slen = strlen(S);
int Tlen = strlen(T);

int Minlen = Slen < Tlen ? Slen : Tlen;
while(a<Minlen&&S[a]==T[a]) a++;
_extend[0] = a;
a = 0;

for(int k = 1; k < Slen; k++) {
int p = a + _extend[a] - 1,L = _next[k-a];
if((k-1)+L>=p) {
int j = (p-k+1) > 0 ? p - k + 1 : 0;
while(k+j<Slen&&j<Tlen&&S[k+j]==T[j]) j++;
_extend[k] = j;
a = k;
}
else
_extend[k] = L;
}

}

void getnext1(char *T) {
int a = 0;
int Tlen = strlen(T);
next1[0] = Tlen;
while(a<Tlen-1&&T[a]==T[a+1]) a++;
next1[1] = a;

a = 1;
for(int k=2; k < Tlen; k++) {
int p = a + next1[a] - 1,L = next1[k-a];
if((k-1)+L>=p) {
int j = (p-k+1) > 0 ? p - k + 1 : 0;
while(k+j<Tlen&&T[k+j]==T[j])
j++;
next1[k] = j;
a = k;
}
else next1[k] = L;
}
}

void getextend1(char *S,char *T) {
int a = 0;
getnext1(T);

int Slen = strlen(S);
int Tlen = strlen(T);

int Minlen = Slen < Tlen ? Slen : Tlen;
while(a<Minlen&&S[a]==T[a]) a++;
extend1[0] = a;
a = 0;

for(int k = 1; k < Slen; k++) {
int p = a + extend1[a] - 1,L = next1[k-a];
if((k-1)+L>=p) {
int j = (p-k+1) > 0 ? p - k + 1 : 0;
while(k+j<Slen&&j<Tlen&&S[k+j]==T[j]) j++;
extend1[k] = j;
a = k;
}
else
extend1[k] = L;
}

}

int main() {
int T;
scanf("%d",&T);
while(T--) {

for(int i = 0; i < 26; i++)
scanf("%d",&a[i]);

scanf("%s",str);

int len = strlen(str);

s[0] = a[ str[0] - 'a' ];
for(int i = 1; i < len; i++)
s[i] = s[i-1] + a[ str[i]-'a' ];

for(int i = 0; i < len; i++)
str1[i] = str[len-i-1];

getextend(str1,str);
getextend1(str,str1);

int ans = 0;
for(int i = 0; i < len-1; i++)
{
if(_extend[len-i-1]==i+1&&extend1[i+1]==len-i-1)
ans = max(ans,s[len-1]);
else if(_extend[len-i-1]==i+1)
ans = max(ans,s[i]);
else if(extend1[i+1]==len-i-1)
ans = max(ans,s[len-1]-s[i]);
}

printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: