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
| #define _CRT_SECURE_NO_WARNINGS #include "iostream" #include "cstring" #include "cstdlib" #include "algorithm" using namespace std; const int maxn = 4002205;
int tHeads[maxn]; int tNode[maxn]; int ncnt = 0; int tNodeVal[maxn];
int trieExistsCount[maxn]; int trieJoinCount[maxn]; int codeMap[] = {-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,0,1,2,3,4,5,6,7,8,9,-3,-2,-1,0,1,2,3,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,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,-189,-188,-187}; void insert() { int p = 0; while (1) { char ch = getchar(); if (ch == '\n') break; ++trieJoinCount[p]; int c = codeMap[ch]; int nex = tHeads[p]; while(nex && tNodeVal[nex] != c) nex = tNode[nex]; if (!nex) { int bf = tHeads[p]; tHeads[p] = ++ncnt; tNode[ncnt] = bf; tNodeVal[ncnt] = c; p = ncnt; } else p = nex; } ++trieExistsCount[p]; ++trieJoinCount[p]; } long long int ans = 0; long long int dc = 0; void dfs(int p,int last) { int f = trieExistsCount[p]; int j = trieJoinCount[p]; if (j && last) { dc += (last - j) * j; ans += j * (j - 1); ans += f * (j - f); ans += f * (f - 1); } int t = j - f; int nex = tHeads[p]; while(nex){ dfs(nex, t); nex = tNode[nex]; } } char S[1005]; int main() { int kase = 0; int n; while (~scanf("%d", &n) && n) { ans = 0, dc = 0, ncnt = 0; memset(trieExistsCount, 0, sizeof(trieExistsCount)); memset(trieJoinCount, 0, sizeof(trieJoinCount)); memset(tHeads, 0, sizeof(tHeads)); getchar(); for (int i = 0; i < n; ++i) { insert(); } dfs(0, 0);
printf("Case %d: %lld\n", ++kase, ans + dc/2);
} return 0; }
|