HDU3613 扩展KMP
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <queue> 7 #include <stack> 8 #include <deque> 9 #include <iostream> 10 using namespace std; 11 typedef long long LL; 12 const int MOD = 1000000007; 13 const int maxn = 40009 + 5; 14 15 int value[30]; 16 int sum[500009], Next[500009], extend1[500009], extend2[500009]; 17 char a[500009], b[500009]; 18 19 void GetNext(char T[], int &m, int Next[]) 20 { 21 int a = 0, p = 0; 22 Next[0] = m; 23 24 for (int i = 1; i < m; i++) 25 { 26 if (i >= p || i + Next[i - a] >= p) 27 { 28 if (i >= p) 29 p = i; 30 31 while (p < m && T[p] == T[p - i]) 32 p++; 33 34 Next[i] = p - i; 35 a = i; 36 } 37 else 38 { 39 Next[i] = Next[i - a]; 40 } 41 } 42 } 43 44 void GetExtend(char s[], int &n, char t[], int &m, int extend[], int Next[]) 45 { 46 int a = 0, p = 0; 47 GetNext(t, m, Next); 48 49 for (int i = 0; i < n; i++) 50 { 51 if (i >= p || i + Next[i - a] >= p) 52 { 53 if (i >= p) 54 { 55 p = i; 56 } 57 58 while (p < n && p - i < m && s[p] == t[p - i]) 59 { 60 p++; 61 } 62 63 extend[i] = p - i; 64 a = i; 65 } 66 else 67 { 68 extend[i] = Next[i - a]; 69 } 70 } 71 } 72 73 int main() 74 { 75 76 int mid1, mid2, head, k, i, j, t; 77 78 scanf("%d", &t); 79 while (t--) 80 { 81 for (i = 0; i < 26; i++) 82 scanf("%d", &value[i]); 83 84 scanf(" %s", a); 85 k = strlen(a); 86 87 sum[0] = value[a[0] - 'a']; 88 for (i = 1; i < k; i++) 89 { 90 sum[i] = sum[i - 1] + value[a[i] - 'a']; 91 } 92 93 for (i = 0; i < k; i++) 94 b[i] = a[k - 1 - i]; 95 96 GetExtend(a, k, b, k, extend1, Next); 97 GetExtend(b, k, a, k, extend2, Next); 98 /* 99 cout << "next: "; 100 for (int i = 0; i < k; i++) 101 cout << Next[i] << " "; 102 103 // 打印 extend 104 cout << "\nextend: "; 105 for (int i = 0; i < k; i++) 106 cout << extend[i] << " "; 107 108 cout << endl 109 << endl; 110 */ 111 head = 0; 112 for (i = 1; i < k - 1; i++) 113 { 114 if (extend1[i] == k - i) 115 { 116 mid2 = sum[k - 1] - sum[i - 1]; 117 } 118 else 119 { 120 mid2 = 0; 121 } 122 123 if (k - i + extend2[k - i] == k) 124 { 125 mid1 = sum[i - 1]; 126 } 127 else 128 { 129 mid1 = 0; 130 } 131 // cout << i << " : " << mid1 << " " << mid2 << endl; 132 if (mid1 + mid2 > head) 133 head = mid1 + mid2; 134 } 135 printf("%d\n", head); 136 } 137 138 return 0; 139 }