2014 Xi'An ACM-ICPC Regional Contest Problem G. The Problem to Slow Down You (回文自动机(模块化写法))
http://codeforces.com/gym/100548
题意:
切换面板:标签 标签 添加新标签  回文自动机、 给2个字符串,问2个字符串中,相等并且都是回文串的对数。
思路:
构建2个PAM.然后奇偶起点分别跑dfs即可。
PAM写成了模块化的形式orz
1/* ***********************************************
2Author :111qqz
3Created Time :2017年11月14日 星期二 20时22分15秒
4File Name :G.cpp
5************************************************ */
6
7#include <bits/stdc++.h>
8#define PB push_back
9#define fst first
10#define sec second
11#define lson l,m,rt<<1
12#define rson m+1,r,rt<<1|1
13#define ms(a,x) memset(a,x,sizeof(a))
14typedef long long LL;
15#define pi pair < int ,int >
16#define MP make_pair
17
18using namespace std;
19const double eps = 1E-8;
20const int dx4[4]={1,0,0,-1};
21const int dy4[4]={0,-1,1,0};
22const int inf = 0x3f3f3f3f;
23const int N=2E5+7;
24struct PAM
25{
26 struct state
27 {
28 int fail,cnt,len;
29 int nxt[26];
30 }st[N];
31 char S[N],RS[N];
32 int n,now,sz;
33 void init()
34 {
35 ms(st,0);
36 st[0].fail = st[1].fail = 1;
37 st[1].len = -1;
38 sz = 1;
39 }
40 void extend(int c,int pos)
41 {
42 int p = now;
43 while (S[pos-st[p].len-1]!=S[pos]) p = st[p].fail;
44 if (!st[p].nxt[c]){
45 int np=++sz,q=st[p].fail;
46 st[np].len=st[p].len+2;
47 while (S[pos-st[q].len-1]!=S[pos]) q=st[q].fail;
48 st[np].fail=st[q].nxt[c];
49 st[p].nxt[c] = np;
50 }
51 now=st[p].nxt[c];
52 st[now].cnt++;
53 }
54 void Cnt()
55 {
56 for ( int i = sz ; i >= 2; i--) st[st[i].fail].cnt += st[i].cnt;
57 }
58 void build ()
59 {
60 init();
61 int len = strlen(S+1);
62 for ( int i = 1 ; i <= len ; i++) extend(S[i]-'a',i);
63 }
64}A,B;
65
66LL ans;
67void dfs( int x,int y)
68{
69 // printf("x:%d y:%d\n",x,y);
70 for ( int i = 0 ; i < 26 ; i++)
71 {
72 int u = A.st[x].nxt[i];
73 int v = B.st[y].nxt[i];
74 if (u&&v)
75 {
76 ans = ans + 1LL*A.st[u].cnt * B.st[v].cnt;
77 // printf("u:%d v:%d ans:%lld\n",u,v,ans);
78 dfs(u,v);
79 }
80 }
81}
82int main()
83{
84#ifndef ONLINE_JUDGE
85 freopen("./in.txt","r",stdin);
86#endif
87 int T,cas = 0 ;
88 cin>>T;
89 while (T--)
90 {
91 scanf("%s %s",A.S+1,B.S+1);
92// cout<<A.S<<" "<<B.S<<endl;
93 A.build();
94 B.build();
95 A.Cnt();
96 B.Cnt();
97 ans = 0 ;
98 dfs(0,0) ;
99 dfs(1,1) ; //奇偶起点
100 printf("Case #%d: %lld\n",++cas,ans);
101 }
102
103
104#ifndef ONLINE_JUDGE
105 fclose(stdin);
106#endif
107 return 0;
108}