题目链接:https://cn.vjudge.net/problem/UVA-11732
题意:
给出n个字符串,两两执行一次strcmp函数,问strcmp函数中== 执行了多少次,具体题意点题目链接查看。
题解:
刘汝佳 算法竞赛入门经典书上的一道题,用孩子兄弟表示法省内存。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=4e6+5;
char s[maxn];
struct Tire{
int head[maxn];
int next[maxn];
int tot[maxn];
char ch[maxn];
int sz;
ll ans;
void clear(){
sz=1; tot[0]=head[0]=next[0]=0;
}
void insert(char *s){
int u=0,v,n=strlen(s);
tot[0]++;
for(int i=0;i<=n;i++){
bool flag=false;
for(v=head[u];v;v=next[v]){
if(ch[v]==s[i]){
flag=true;
break;
}
}
if(!flag){
v=sz++;
tot[v]=0;
ch[v]=s[i];
next[v]=head[u];
head[u]=v;
head[v]=0;
}
u=v;
tot[u]++;
}
}
void dfs(int depth,int u){
if(head[u]==0){
ans+=tot[u]*(tot[u]-1)*depth;
}else{
int sum=0;
for(int v=head[u];v;v=next[v]){
sum+=tot[v]*(tot[u]-tot[v]);
}
ans+=sum/2*(2*depth+1);
for(int v=head[u];v;v=next[v]){
dfs(depth+1,v);
}
}
}
ll count(){
ans=0;
dfs(0,0);
return ans;
}
};
Tire tire;
int main(){
int n;
int cnt=1;
while(scanf("%d",&n)&&n){
tire.clear();
while(n--){
scanf("%s",s);
tire.insert(s);
}
printf("Case %d: %lld\n",cnt++,tire.count());
}
return 0;
}