# bzoj 4084 双旋转字符串

  1 /**************************************************************
2     Problem: 4084
3     User: idy002
4     Language: C++
5     Result: Accepted
6     Time:6456 ms
7     Memory:290272 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #include <set>
12 #include <vector>
13 #include <algorithm>
14 #define N 8000010
15 #define Base 31
16 #define Mod 1000000007
17 using namespace std;
18
19 typedef long long dnt;
20
21 int n, m, ln, lm;
22 char *sa[N], *sb[N];
23 char buf_arr[N], *buf=buf_arr;
24 dnt fx[N], sx[N], pow[N];
25 int fail[N];
26 multiset<int> stb;
27
28 int hash( char *s ) {
29     dnt rt = 0;
30     for( int i=0; s[i]; i++ )
31         rt = (rt*Base + s[i]-'a') % Mod;
32     return rt;
33 }
34 void init_hash( int ln, char *s ) {     //  ln>=1
35     fx[0] = s[0]-'a';
36     for( int j=1; j<ln; j++ )
37         fx[j] = (fx[j-1]*Base + s[j]-'a') % Mod;
38     sx[ln-1] = s[ln-1]-'a';
39     for( int j=ln-2; j>=0; j-- )
40         sx[j] = ((s[j]-'a')*pow[ln-1-j] + sx[j+1]) % Mod;
41 }
42 void init_fail( char *s ) {
43     fail[0] = 0;
44     fail[1] = 0;
45     for( int i=1; s[i]; i++ ) {
46         int j=fail[i];
47         while( j && s[j]!=s[i] ) j=fail[j];
48         if( s[j]==s[i] )
49             fail[i+1]=j+1;
50         else
51             fail[i+1]=0;
52     }
53 }
54 void work1() {  //  ln > lm
55     vector<int> vc;
56     int ll = (ln+lm)>>1;
57     dnt ans = 0;
58     for( int t=1; t<=n; t++ ) {
59         init_fail(sa[t]+ll);
60         for( int i=0; i<ll; i++ )
61             buf[i] = sa[t][i];
62         for( int i=0; i<ll; i++ )
63             buf[ll+i] = sa[t][i];
64         init_hash(ll+ll,buf);
65         vc.clear();
66         int i=0, j=0;
67         while( i<ln-1 ) {
68             while( i<ln-1 && j<ln-ll && buf[i]==sa[t][ll+j] ) i++, j++;
69             if( j==ln-ll ) {
70                 dnt v;
71                 v = fx[i+(ll+ll-ln)-1]-fx[i-1]*pow[ll+ll-ln];
72                 v = (v%Mod+Mod) % Mod;
73                 vc.push_back(v);
74                 j = fail[ln-ll];
75             }
76             if( i==ln-1 ) break;
77             while( j && sa[t][ll+j]!=buf[i] ) j=fail[j];
78             if( sa[t][ll+j]!=buf[i] ) i++;
79         }
80         sort( vc.begin(), vc.end() );
81         vc.erase( unique(vc.begin(),vc.end()), vc.end() );
82         for( int t=0; t<vc.size(); t++ )
83             ans += stb.count(vc[t]);
84     }
85     printf( "%lld\n", ans );
86 }
87 void work3() {  //  ln = lm
88     vector<int> vc;
89     dnt ans = 0;
90     for( int i=1; i<=n; i++ ) {
91         init_hash(ln,sa[i]);
92         vc.clear();
93         vc.push_back( sx[0] );
94         for( int j=1; j<ln; j++ ) {
95             int v = ((dnt)sx[j]*pow[j]+fx[j-1]) % Mod;
96             vc.push_back(v);
97         }
98         sort( vc.begin(), vc.end() );
99         vc.erase( unique(vc.begin(), vc.end()), vc.end() );
100         for( int t=0; t<vc.size(); t++ )
101             ans += stb.count(vc[t]);
102     }
103     printf( "%lld\n", ans );
104 }
105 int main() {
106     scanf( "%d%d%d%d", &n, &m, &ln, &lm );
107     if( ln>lm ) {
108         for( int i=1; i<=n; i++ ) {
109             scanf( "%s", buf );
110             sa[i] = buf;
111             buf += ln+1;
112         }
113         for( int i=1; i<=m; i++ ) {
114             scanf( "%s", buf );
115             sb[i] = buf;
116             buf += lm+1;
117         }
118     } else {
119         swap(n,m);
120         swap(ln,lm);
121         for( int i=1; i<=m; i++ ) {
122             scanf( "%s", buf );
123             sb[i] = buf;
124             reverse( buf, buf+lm );
125             buf += lm+1;
126         }
127         for( int i=1; i<=n; i++ ) {
128             scanf( "%s", buf );
129             sa[i] = buf;
130             reverse( buf, buf+ln );
131             buf += ln+1;
132         }
133     }
134     pow[0] = 1;
135     for( int i=1; i<=ln; i++ )
136         pow[i] = pow[i-1]*Base % Mod;
137     for( int i=1; i<=m; i++ )
138         stb.insert( hash(sb[i]) );
139     if( ln!=lm )
140         work1();
141     else
142         work3();
143 }
View Code

posted @ 2015-06-16 15:05  idy002  阅读(520)  评论(0编辑  收藏  举报