# BZOJ 2084: [Poi2010]Antisymmetry

## 2084: [Poi2010]Antisymmetry

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 596  Solved: 379
[Submit][Status][Discuss]

8
11001011

## Sample Output

7

hint
7个反对称子串分别是：01(出现两次), 10(出现两次), 0101, 1100和001011

## Source

[Submit][Status][Discuss]

 1 #include <cstdio>
2
3 const int siz = 1000005;
4
5 int n;
6 int s[siz];
7 int r[siz];
8 char str[siz];
9
10 inline int min(int a, int b)
11 {
12     return a < b ? a : b;
13 }
14
15 inline bool check(int a, int b)
16 {
17     return
18         (a == 0 && b == 1)
19     ||  (a == 1 && b == 0)
20     ||  (a == 3 && b == 3);
21 }
22
23 signed main(void)
24 {
25     scanf("%d%s", &n, str + 1);
26
27     /*<--- Prework --->*/
28
29
30     for (int i = 1; i <= n; ++i)
31     {
32         static int tot = 0;
33         s[++tot] = 3;
34         s[++tot] = str[i] - '0';
35     }
36
37     n = 2*n + 1;
38
39     s[n] = 3;
40     s[0] = 4;
41     s[n + 1] = 4;
42
43     /*<--- Manacher --->*/
44
45     for (int i = 1; i <= n; i += 2)
46     {
47         static int maxi = 0, id = 0;
48
49         if (i <= maxi)
50             r[i] = min(maxi - i + 1, r[2*id - i]);
51         else
52             r[i] = 1;
53
54         while (check(s[i + r[i]], s[i - r[i]]))
55             ++r[i];
56
57         if (maxi < r[i] + i - 1)
58             maxi = r[i] + i - 1, id = i;
59     }
60
61     /*<--- Calculate --->*/
62
63     long long ans = 0LL;
64
65     for (int i = 1; i <= n; i += 2)
66         ans += (r[i] - 1) >> 1;
67
68     printf("%lld\n", ans);
69 }

@Author: YouSiki

posted @ 2017-01-15 11:16  YouSiki  阅读(203)  评论(0编辑  收藏  举报