BZOJ2084: [Poi2010]Antisymmetry

$n \leq 500000$的01串,1跟0配,问最长回文子串。

$0=1$,$1 \neq 1$,$0 \neq 0$,然后二分哈希或manacher或回文树。

 1 //#include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 //#include<time.h>
 5 //#include<complex>
 6 //#include<set>
 7 //#include<queue>
 8 #include<algorithm>
 9 #include<stdlib.h>
10 using namespace std;
11 
12 #define LL long long
13 int qread()
14 {
15     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
16     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
17 }
18 
19 //Pay attention to '-' , LL and double of qread!!!!
20 
21 int n;
22 #define maxn 500011
23 char s[maxn];
24 struct PT
25 {
26     struct Node{int ch[2],pre,len,cnt;}a[maxn];
27     int last,size;
28     PT() {last=size=1; a[1].pre=0; a[1].len=0;}
29     void insert(int c,int p)
30     {
31 //        cout<<p<<' '<<last<<"!!!!!\n";
32         int y=last,len;
33         while (y)
34         {
35 //            cout<<y<<' '<<a[y].len<<' '<<a[y].pre<<endl;
36             len=a[y].len;
37             if (p-len-1>=1 && s[p-len-1]!=s[p]) break;
38             y=a[y].pre;
39         }
40         if (!y) {last=1; return;}
41 //        cout<<y<<' '<<a[y].len<<' '<<a[y].pre<<endl;
42         if (a[y].ch[c]) {last=a[y].ch[c]; a[last].cnt++; return;}
43         int x=last=++size;
44         a[x].len=a[y].len+2; a[y].ch[c]=x; a[x].cnt=1;
45         while (y)
46         {
47             y=a[y].pre; len=a[y].len;
48             if (p-len-1>=1 && s[p-len-1]!=s[p])
49             {
50                 a[x].pre=a[y].ch[c];
51                 break;
52             }
53         }
54         if (!a[x].pre) a[x].pre=1;
55     }
56 //    void test()
57 //    {
58 //        for (int i=1;i<=size;i++) cout<<a[i].len<<' '<<a[i].pre<<' '<<a[i].cnt<<endl;
59 //    }
60     void hei()
61     {
62         for (int i=size;i;i--) a[a[i].pre].cnt+=a[i].cnt;
63     }
64 }pt;
65 
66 int main()
67 {
68     scanf("%d",&n); scanf("%s",s+1);
69     for (int i=1;i<=n;i++) pt.insert(s[i]-'0',i);
70 //    pt.test();
71     pt.hei();
72     int ans=0; for (int i=2;i<=pt.size;i++) ans+=pt.a[i].cnt;
73     printf("%d\n",ans);
74     return 0;
75 }
View Code

 

posted @ 2018-04-28 11:25  Blue233333  阅读(183)  评论(0编辑  收藏  举报