bzoj 3325 密码 - Manacher
考虑Manacher的过程,假设当前扩展得最远的端点是$mx$。
$mx$之内的部分可以根据回文串的性质直接判掉,当$mx$被更新的时候才会出现新的相等关系。
由于题目给出的是最长回文串串长,所以还需要一些不等关系。
因为字符集很小,所以直接开数组打标记就好了。
Code
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef bool boolean; 4 5 const int N = 1e5 + 3, alpha = 26; 6 7 int n; 8 int ar[N], br[N]; 9 boolean ban[N][alpha]; 10 char s[N]; 11 12 inline void init() { 13 scanf("%d", &n); 14 for (int i = 1; i <= n; i++) 15 scanf("%d", ar + i); 16 for (int i = 1; i < n; i++) 17 scanf("%d", br + i); 18 } 19 20 inline void solve() { 21 int mx = 1, r, l; 22 for (int i = 1; i < n; i++) { 23 if (!s[i]) { 24 for ( ; ban[i][s[i]]; s[i]++); 25 s[i] += 'a'; 26 } 27 r = i + (ar[i] >> 1), l = i - (ar[i] >> 1); 28 if (mx < r) { 29 for (mx = mx + 1 ; mx < r; mx++) 30 s[mx] = s[2 * i - mx]; 31 s[mx] = s[2 * i - mx]; 32 } 33 if (l > 1) 34 ban[r + 1][s[l - 1] - 'a'] = true; 35 r = i + (br[i] >> 1), l = r - br[i] + 1; 36 if (mx < r) { 37 for (mx = mx + 1 ; mx < r; mx++) 38 s[mx] = s[2 * i - mx + 1]; 39 s[mx] = s[2 * i - mx + 1]; 40 } 41 if (l > 1) 42 ban[r + 1][s[l - 1] - 'a'] = true; 43 } 44 if (!s[n]) { 45 for ( ; ban[n][s[n]]; s[n]++); 46 s[n] += 'a'; 47 } 48 puts(s + 1); 49 } 50 51 int main() { 52 init(); 53 solve(); 54 return 0; 55 }