您的位置:首页 > 其它

UVA - 11732 "strcmp()" Anyone?左兄弟右儿子trie

2015-12-03 11:18 369 查看
input

n 2<=n<=4000

s1

s2

...

sn

1<=len(si)<=1000

output

输出用strcmp()两两比较si,sj(i!=j)要比较的次数,结果在long long范围内(相同字符比较两次,不相同字符比较一次,包括'\0')

做法:由于字符集太大,要用左兄弟右儿子的trie保存字符,不用每次都开ch[62]个孩子

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

#define repf(i,a,b) for(int i=(a);i<=(b);i++)
typedef long long ll;

const int N = 0;
const int MAXNODE = 4000010;

int n, cas;
ll ans;
char str[4001];

struct STrie {
int son[MAXNODE];
int bro[MAXNODE];
int val[MAXNODE];
char ch[MAXNODE];
int sz;

STrie() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; }
void init() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; }
// inline int idx(char c) { return c - 'a'; }

void insert(char *s) {
int len = strlen(s), u = 0, p;
repf (i, 0, len) {
// check the brother of u
for (p = son[u]; p; p = bro[p]) {
if (ch[p] == s[i])
break;
}
// cannot find out than insert
if (!p) {
p = sz++;
ch[p] = s[i];
bro[p] = son[u];
son[p] = 0;
val[p] = 0;
son[u] = p;
}
ans += (val[u] - val[p]) * (2 * i + 1);
if (len == i) {
ans += val[p] * (2 * i + 2);
val[p]++;
}
val[u]++;
u = p;
}
}
} trie;

int main() {
// ios_base::sync_with_stdio(0);
while (~scanf("%d", &n) && n) {
trie.init();
ans = 0;
repf (i, 0, n - 1) {
scanf("%s", str);
trie.insert(str);
}
printf("Case %d: %lld\n", ++cas, ans);
}
return 0;
}


copy Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: