您的位置:首页 > 其它

UVa 11732 strcmp()函数(左孩子右兄弟表示法)

2017-03-29 23:10 323 查看
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
using namespace std;

const int maxn = 4000 * 1000 + 10;
int n;
long long ans;

struct Trie
{
int head[maxn];     //head[i]为第i个结点的左儿子编号
int next[maxn];     //next[i]为第i个结点的右兄弟编号
char ch[maxn];      //第i个结点上的字符
int tot[maxn];
int sz;

void init()
{
sz = 1;
head[0] = tot[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 found = false;
for (v = head[u]; v != 0; v = next[v])
{
if (ch[v] == s[i])
{
found = true;
break;
}
}
if (!found)
{
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 != 0; v = next[v])
sum += tot[v] * (tot[u] - tot[v]);
ans += sum / 2 * (2 * depth + 1);
for (int v = head[u]; v != 0; v = next[v])
dfs(depth + 1, v);
}
}
}t;

int main()
{
//freopen("D:\\txt.txt", "r", stdin);
char str[1005];
int kase = 0;
while (~scanf("%d", &n), n)
{
t.init();
while (n--)
{
scanf("%s", str);
t.insert(str);
}
ans = 0;
t.dfs(0,0);
printf("Case %d: %lld\n", ++kase, ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: