input
n 2<=n<=4000
s1
s2
...
sn
1<=len(si)<=1000
output
输出用strcmp()两两比较si,sj(i!=j)要比较的次数,结果在long long范围内(相同字符比较两次,不相同字符比较一次,包括‘\0‘)
做法:由于字符集太大,要用左兄弟右儿子的trie保存字符,不用每次都开ch[62]个孩子
1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #include <iostream> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #include <ctime> 11 #include <cmath> 12 #include <cctype> 13 #define MAX 100000 14 #define LL long long 15 #define mod 20071027 16 struct node 17 { 18 int sz; 19 char val; 20 node*ch[2]; //ch[1]兄弟,ch[0]儿子 21 node() 22 { 23 ch[0]=ch[1]=NULL; 24 sz=0; 25 } 26 }; 27 char word[1010]; 28 int n,cas=1; 29 long long sum; 30 long long insert(char*s,node*u) 31 { 32 long long sum=0,lastsz=u->sz++; 33 for(;*s||*(s-1);s++) 34 { 35 if(!u->ch[0]) //易错,要先把新建的结点连接到父结点才能往下走,否则新建之后父节点无法再读取到该结点 36 { 37 u->ch[0]=new node; 38 u->ch[0]->val=*s; 39 } 40 for(u=u->ch[0];u->val!=*s;u=u->ch[1]) 41 { 42 if(!u->ch[1]) 43 { 44 u->ch[1]=new node; 45 u->ch[1]->val=*s; 46 } 47 } 48 sum+=lastsz+u->sz; 49 lastsz=u->sz++; 50 } 51 return sum; 52 } 53 void freenode(node*u) 54 { 55 if(u==NULL) return; 56 freenode(u->ch[0]); 57 freenode(u->ch[1]); 58 delete u; 59 } 60 int main() 61 { 62 //freopen("/home/user/桌面/in","r",stdin); 63 while(scanf("%d",&n)==1&&n) 64 { 65 sum=0; 66 node *root=new node; 67 while(n--) 68 { 69 scanf("%s",word); 70 sum+=insert(word,root); 71 } 72 printf("Case %d: %lld\n",cas++,sum); 73 freenode(root); 74 } 75 //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC); 76 return 0; 77 }
my Code
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 #define repf(i,a,b) for(int i=(a);i<=(b);i++) 8 typedef long long ll; 9 10 const int N = 0; 11 const int MAXNODE = 4000010; 12 13 int n, cas; 14 ll ans; 15 char str[4001]; 16 17 struct STrie { 18 int son[MAXNODE]; 19 int bro[MAXNODE]; 20 int val[MAXNODE]; 21 char ch[MAXNODE]; 22 int sz; 23 24 STrie() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; } 25 void init() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; } 26 // inline int idx(char c) { return c - ‘a‘; } 27 28 void insert(char *s) { 29 int len = strlen(s), u = 0, p; 30 repf (i, 0, len) { 31 // check the brother of u 32 for (p = son[u]; p; p = bro[p]) { 33 if (ch[p] == s[i]) 34 break; 35 } 36 // cannot find out than insert 37 if (!p) { 38 p = sz++; 39 ch[p] = s[i]; 40 bro[p] = son[u]; 41 son[p] = 0; 42 val[p] = 0; 43 son[u] = p; 44 } 45 ans += (val[u] - val[p]) * (2 * i + 1); 46 if (len == i) { 47 ans += val[p] * (2 * i + 2); 48 val[p]++; 49 } 50 val[u]++; 51 u = p; 52 } 53 } 54 } trie; 55 56 int main() { 57 // ios_base::sync_with_stdio(0); 58 while (~scanf("%d", &n) && n) { 59 trie.init(); 60 ans = 0; 61 repf (i, 0, n - 1) { 62 scanf("%s", str); 63 trie.insert(str); 64 } 65 printf("Case %d: %lld\n", ++cas, ans); 66 } 67 return 0; 68 }
copy Code
时间: 2024-09-30 10:52:37