FOJ 2013 11 月赛 F
Problem 2137 奇异字符串
Accept: 33 Submit: 149
Time Limit: 1000 mSec Memory Limit : 32768 KB
我就是个傻逼,虽然这题超时了,但我的时间真的向水一样的丢在上面!
Problem Description
seen喜欢一种特殊的字符串,seen称这种字符串为奇异字符串。奇异字符串可以表示为AxA这种形式,A为一个任意非空字符串,只包含小写字母,x为一个不在A中出现过的小写字母。seen认为一个长度为d的奇异字符串的价值为d*d,不是奇异字符串的字符串没有价值。现给一个只包含小写字母的字符串,统计其所有子串的价值总和。一个字符串的子串是指其中连续的一段字符构成的字符串。这里相同的子串如果在原串中出现的位置不同则视为不同,需要分别进行统计。
Input
第一行一个整数T,表示有T组数据。
每组数据输入一行只包含小写字母的非空字符串,长度不超过100000。
Output
对于每组数据输出一行表示所有子串的价值总和。
Sample Input
1
abcdabc
Sample Output
49
1 #include <cstdio> 2 #include <vector> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 #define maxn 100005 7 #define INF 0x7fffffff 8 #define ll long long 9 ll n,m; 10 ll ans; 11 vector<int>g[27]; 12 char s[maxn]; 13 ll sa[maxn], t1[maxn], t2[maxn], c[maxn]; 14 ll rnk[maxn], height[maxn], d[maxn][21],v[maxn]; 15 void RMQ_init(){ 16 for (int i = 0; i < n; i++)d[i][0] = height[i]; 17 for (int j = 1; (1 << j) <= n;j++) 18 for (int i = 0; i + (1 << j) - 1 < n; i++) 19 d[i][j] = min(d[i][j - 1], d[i + (1 << (j - 1))][j - 1]); 20 } 21 int lcp(ll a, ll b){ 22 a = rnk[a]; b = rnk[b]; 23 if (a > b)swap(a, b); 24 a++; 25 int t = v[b - a + 1]; 26 return min(d[a][t], d[b-(1<<t)+1][t]); 27 } 28 void getheight(){ 29 int i, j, k = 0; 30 for (i = 0; i < n; i++)rnk[sa[i]] = i; 31 for (i = 0; i < n; i++){ 32 if (k)k--; 33 if (rnk[i] - 1 < 0)continue; 34 int j = sa[rnk[i]-1]; 35 while (s[i + k] == s[j + k])k++; 36 height[rnk[i]] = k; 37 } 38 } 39 void suffix(int m){ 40 ll *x = t1, *y = t2; 41 int i; 42 for (i = 0; i < m; i++)c[i] = 0; 43 for (i = 0; i < n; i++)c[x[i] = s[i]-'a']++; 44 for (i = 1; i < m; i++)c[i] += c[i - 1]; 45 for (i = n - 1; i >= 0; i--)sa[--c[x[i]]] = i; 46 for (int k = 1; k <= n; ){ 47 int p = 0; 48 for (i = n - k; i < n; i++)y[p++] = i; 49 for (i = 0; i < n; i++)if (sa[i] >= k)y[p++] = sa[i] - k; 50 for (i = 0; i < m; i++)c[i] = 0; 51 for (i = 0; i < n; i++)c[x[y[i]]]++; 52 for (i = 1; i < m; i++)c[i] += c[i - 1]; 53 for (i = n - 1; i >= 0; i--)sa[--c[x[y[i]]]] = y[i]; 54 swap(x, y); 55 p = 1; x[sa[0]] = 0; 56 for (i = 1; i < n; i++)x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++; 57 if (p >= n)break; 58 m = p; 59 k <<= 1; 60 } 61 getheight(); 62 } 63 ll fun(ll a, ll b){ 64 int x = lcp(a, b); 65 if (x!=INF&&x>= b - a - 1)return ((b-a)*2-1)*((b-a)*2-1); 66 return 0; 67 } 68 int main(){ 69 int t; 70 for (int i = 0; i < maxn; i++) 71 v[i] = (i&(i - 1)) ? v[i - 1] : v[i - 1] + 1; 72 for (int i = 0; i < maxn; i++)v[i] -= 2; 73 v[1] = 0; v[2] = v[3] = 1; 74 scanf("%d", &t); 75 while (t--){ 76 for (int i = 0; i < 26; i++)g[i].clear(); 77 scanf("%s", s); 78 n = strlen(s); 79 m = 0; 80 ans = 0; 81 v[0] = -1; 82 for (int i = 0; i < n; i++)for (int j = 0; i+(1<<j) <= n; j++)d[i][j] = INF; 83 suffix(26); 84 RMQ_init(); 85 for (int i = 0; i < n; i++)g[s[i] - 'a'].push_back(i); 86 for (int i = 0; i < 26; i++){ 87 int d=0; 88 for (int j = 0; j < g[i].size(); j++){ 89 if (j == 0 && j == g[i].size() - 1)d = min((ll)g[i][j], n - 1 - g[i][j]); 90 else{ 91 if (j == 0)d = min(g[i][j], g[i][j + 1] - g[i][j]-1); 92 else if (j == g[i].size() - 1)d = min((ll)g[i][j] - g[i][j - 1]-1, n - 1 - g[i][j]); 93 else d = min(g[i][j] - g[i][j - 1]-1, g[i][j + 1] - g[i][j]-1); 94 } 95 for (int k = d; k >= 1; k--){ 96 ll x = 0; 97 if (g[i][j] + 1<n)x = fun(g[i][j] - k, g[i][j] + 1); 98 if (x > 0){ 99 ans += x; 100 k--; 101 } 102 } 103 } 104 } 105 printf("%I64d\n", ans); 106 } 107 }
浙公网安备 33010602011771号