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 <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
#define MAX 100000
#define LL long long
#define mod 20071027
struct node
{
int sz;
char val;
node*ch[]; //ch[1]兄弟,ch[0]儿子
node()
{
ch[]=ch[]=NULL;
sz=;
}
};
char word[];
int n,cas=;
long long sum;
long long insert(char*s,node*u)
{
long long sum=,lastsz=u->sz++;
for(;*s||*(s-);s++)
{
if(!u->ch[]) //易错,要先把新建的结点连接到父结点才能往下走,否则新建之后父节点无法再读取到该结点
{
u->ch[]=new node;
u->ch[]->val=*s;
}
for(u=u->ch[];u->val!=*s;u=u->ch[])
{
if(!u->ch[])
{
u->ch[]=new node;
u->ch[]->val=*s;
}
}
sum+=lastsz+u->sz;
lastsz=u->sz++;
}
return sum;
}
/*//这样可以将父节点的ch和新建的结点绑定起来,传过来的是&root
long long insert(char*s,node**u)
{
long long sum=0,lastsz=(*u)->sz++;
for(;*s||*(s-1);s++)
{
printf("%p\n",u);
for(u=&((*u)->ch[0]);(*u)&&(*u)->val!=*s;u=&((*u)->ch[1]));
if(*u==NULL)
{
*u=new node;
(*u)->ch[0]=(*u)->ch[1]=NULL;
(*u)->val=*s;
}
sum+=lastsz+(*u)->sz;
lastsz=(*u)->sz++;
}
return sum;
}*/
void freenode(node*u)
{
if(u==NULL) return;
freenode(u->ch[]);
freenode(u->ch[]);
delete u;
}
int main()
{
//freopen("/home/user/桌面/in","r",stdin);
while(scanf("%d",&n)==&&n)
{
sum=;
node *root=new node;
while(n--)
{
scanf("%s",word);
sum+=insert(word,root);
}
printf("Case %d: %lld\n",cas++,sum);
freenode(root);
}
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return ;
} my Code

my Code

 #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 = ;
const int MAXNODE = ; int n, cas;
ll ans;
char str[]; struct STrie {
int son[MAXNODE];
int bro[MAXNODE];
int val[MAXNODE];
char ch[MAXNODE];
int sz; STrie() { sz = ; ch[] = val[] = bro[] = son[] = ; }
void init() { sz = ; ch[] = val[] = bro[] = son[] = ; }
// inline int idx(char c) { return c - 'a'; } void insert(char *s) {
int len = strlen(s), u = , p;
repf (i, , 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] = ;
val[p] = ;
son[u] = p;
}
ans += (val[u] - val[p]) * ( * i + );
if (len == i) {
ans += val[p] * ( * i + );
val[p]++;
}
val[u]++;
u = p;
}
}
} trie; int main() {
// ios_base::sync_with_stdio(0);
while (~scanf("%d", &n) && n) {
trie.init();
ans = ;
repf (i, , n - ) {
scanf("%s", str);
trie.insert(str);
}
printf("Case %d: %lld\n", ++cas, ans);
}
return ;
}

copy Code

UVA - 11732 "strcmp()" Anyone?左兄弟右儿子trie的更多相关文章

  1. 左儿子右兄弟Trie UVA 11732 strcmp() Anyone?

    题目地址: option=com_onlinejudge&Itemid=8&category=117&page=show_problem&problem=2832&qu ...

  2. UVA 11732 - strcmp() Anyone?(Trie)

    UVA 11732 - strcmp() Anyone? 题目链接 题意:给定一些字符串,要求两两比較,须要比較的总次数(注意.假设一个字符同样.实际上要还要和'\0'比一次,相当比2次) 思路:建T ...

  3. UVa 11732 "strcmp()" Anyone? (左儿子右兄弟前缀树Trie)

    题意:给定strcmp函数,输入n个字符串,让你用给定的strcmp函数判断字符比较了多少次. 析:题意不理解的可以阅读原题https://uva.onlinejudge.org/index.php? ...

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

    #include<iostream> #include<algorithm> #include<string> #include<cstring> #i ...

  5. UVA 11732 - strcmp() Anyone? 字典树

    传送门:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  6. Uva 11732 strcmp() Anyone?

    strcmp() Anyone? Time Limit: 2000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu [Subm ...

  7. UVA 11732 strcmp() Anyone?(Trie的性质)

    strcmp() Anyone? strcmp() is a library function in C/C++ which compares two strings. It takes two st ...

  8. UVA - 11732 "strcmp()" Anyone? (trie)

    https://vjudge.net/problem/UVA-11732 题意 给定n个字符串,问用strcmp函数比较这些字符串共用多少次比较. strcmp函数的实现 int strcmp(cha ...

  9. UVA 11732 strcmp() Anyone? (压缩版字典树)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

随机推荐

  1. asp.net分页代码(教你怎么实现)

    直接上代码: css部分代码 .pageCss { float: right; width: auto; height: 30px; line-height: 30px; margin-right: ...

  2. UVA 624 CD (01背包)

    //路径记录方法:若是dp[j-value[i]]+value[i]>dp[j]说明拿了这个东西,标志为1, //for循环标志,发现是1,就打印出来,并把背包的容量减少,再在次容量中寻找标志: ...

  3. Gentoo挂载ntfs的NTFS分区

    内核需要开启的选项 File systems ---> <*> FUSE (Filesystem in Userspace) support 使用NTFS-3G NTFS-3G是一个 ...

  4. 万航单位换算器 V1.0 绿色版

    软件名称: 万航单位换算器软件语言: 简体中文授权方式: 免费软件运行环境: Win 32位/64位软件大小: 347KB图片预览: 软件简介:万航单位换算器是一个可以随意转换单位的绿色软件,这个软件 ...

  5. 菲菲更名宝贝(批量更名软件) v8.0 绿色版

    软件名称: 菲菲更名宝贝(批量更名软件)软件语言: 简体中文授权方式: 免费软件运行环境: Win7 / Vista / Win2003 / WinXP 软件大小: 1.5MB图片预览: 软件简介:菲 ...

  6. 调用CImg库显示WAV格式音频波形

    最近在做傅里叶变换和小波变换时经常要通过显示波形来检验算法,但通过visual studio之类显示波形又显得麻烦,而且不能跨平台. CImg是一个跨平台的C++的图像处理库,提供的图像处理等功能十分 ...

  7. .h 与 .hpp 文件

    hpp,顾名思义等于.h加上.cpp,在boost.Xerces等开源库中频繁出现,偶在机缘巧合之下,学得一招半式,遂记录如下,以供参考学习.     hpp,其实质就是将.cpp的实现代码混入.h头 ...

  8. POJ1410 Intersection 计算几何

    题目大意:给出一个线段的两端,和矩形两端(不一定是左上和右下),问线段是否与矩形相交(若线段在矩形内也算相交).这题蒸鹅心-- 题目思路:判断所有情况:线段是否在矩形内,线段内一点是否在矩形内,线段是 ...

  9. Python基础篇-day2

    主要内容: for循环 while循环 格式化输出(2) 数据统计及记录 ############################################################# 1 ...

  10. 完美版cookie设置/得到/删除2016/423

    function setCookie(key, value, t) { var oDate = new Date(); oDate.setDate( oDate.getDate() + t ); do ...