-
Notifications
You must be signed in to change notification settings - Fork 0
/
E.cpp
117 lines (112 loc) · 2.39 KB
/
E.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "bits/stdc++.h"
using namespace std;
typedef pair <long long, long long> pii;
int count(vector <pii> s) {
int n = s.size();
if(n == 0) return 0;
vector<vector<int>> p(2,vector<int>(n,0));
for(int z=0,l=0,r=0;z<2;z++,l=0,r=0) {
for(int i=0;i<n;i++)
{
if(i<r) p[z][i]=min(r-i+!z,p[z][l+r-i+!z]);
int L=i-p[z][i], R=i+p[z][i]-!z;
while(L-1>=0 && R+1<n && s[L-1]==s[R+1]) p[z][i]++,L--,R++;
if(R>r) l=L,r=R;
}
}
int ans = 0;
for(int i = 0; i < n; i++) {
// cout << p[0][i] << ' ' << p[1][i] << endl;
ans += p[0][i] + p[1][i] + 1;
}
return ans;
}
const int mod = 1000000000 + 7;
const int base = 129;
long long rand64() {
long long ans = 0;
for(int i = 0; i < 62; i++) {
if(rand() & 1) {
ans ^= 1LL << i;
}
}
return ans;
}
long long rand32() {
long long ans = 0;
for(int i = 0; i < 31; i++) {
if(rand() & 1) {
ans ^= 1LL << i;
}
}
return ans;
}
long long modpow(long long b, long long e) {
if(e == 0) return 1;
if(e & 1) {
return (modpow(b, e - 1) * b) % mod;
}
long long m = modpow(b, e >> 1);
return (m * m) % mod;
}
long long inverse(long long x) {
return modpow(x, mod - 2);
}
long long H[252][252];
long long M[252][252];
long long S[252][252];
long long I[252][252];
char s[252][252];
long long mp[30];
long long np[30];
unordered_set <long long> good;
int n, m;
int solve(int x, int y) {
int ans = 0;
vector <pii> v;
for(int i = 1; i <= n; i++) {
long long prod = (M[i][y] * I[i][x - 1]) % mod;
long long sum = (S[i][y] - S[i][x - 1]);
long long xorsum = H[i][y] ^ H[i][x - 1];
if(good.find(xorsum) == good.end()) {
ans += count(v);
v.clear();
} else {
v.emplace_back(prod, sum);
}
}
ans += count(v);
return ans;
}
int main(int argc, char const *argv[])
{
srand(time(NULL));
for(int i = 0; i < 26; i++) {
mp[i] = rand64();
np[i] = rand32();
good.insert(mp[i]);
}
good.insert(0);
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) {
scanf("%s", s[i] + 1);
}
for(int i = 1; i <= n; i++) {
M[i][0] = I[i][0] = 1;
for(int x = 1; x <= m; x++) {
S[i][x] = S[i][x - 1] + np[s[i][x] - 'a'];
H[i][x] = H[i][x - 1] ^ mp[s[i][x] - 'a'];
M[i][x] = M[i][x - 1] * np[s[i][x] - 'a'];
M[i][x] %= mod;
I[i][x] = inverse(M[i][x]);
}
}
long long ans = 0;
for(int i = 1; i <= m; i++) {
for(int j = i; j <= m; j++) {
ans += solve(i, j);
}
}
printf("%lld\n", ans);
return 0;
}