码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 3325 密码 - Manacher

时间:2018-03-25 12:02:53      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:ace   www.   bzoj   权限   bit   std   bool   order   code   

题目传送门

  需要root权限的传送点

题目大意

  已知一个串,以每个字符为中心的最长回文串长,以及每两个字符中间为中心的最长回文串长。求字典序最小的这样一个串。题目保证有解。

  考虑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 }

bzoj 3325 密码 - Manacher

标签:ace   www.   bzoj   权限   bit   std   bool   order   code   

原文地址:https://www.cnblogs.com/yyf0309/p/8643270.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!