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. Spring入门学习(一)

    Spring的主要功能是控制反转和面向切面编程,下面我们就来编写第一个spring的程序来体验一下控制反转 首先是加载配置文件 <?xml version="1.0" enc ...

  2. 面试中有关C++的若干问题

    面试中有关C++的若干问题 By 晴天, 2014.5.16晚 什么是多态?简要说一下C++中的多态的概念. (1)定义:多态是指相同对象收到不同消息或者不同对象收到相同消息产生不同的行为. (2)C ...

  3. Storm 分配逻辑

    ps:都是学习的别人的博客,只是做了个整理所有就写成了原创,其实都是人家的东西 当一个topology在storm cluster中运行时,它的并发主要跟3个逻辑对象相关:worker,executo ...

  4. C# 语言规范_版本5.0 (第2章 词法结构)

    1. 词法结构 1.1 程序 C# 程序 (program) 由一个或多个源文件 (source file) 组成,源文件的正式名称是编译单元 (compilation unit)(第 9.1 节). ...

  5. nefu 1191 平行宇宙 (bfs)

    Description 小k是时空贸易者,他经常在两个平行宇宙之间往来经商,现在他要从S点到达E点,问最少需要多长时间.(已知小k在同一个宇宙中只能向上下左右四个方向移动,每次移动需要1个单位时间,且 ...

  6. Openjudge-计算概论(A)-谁考了第k名

    描述: 在一次考试中,每个学生的成绩都不相同,现知道了每个学生的学号和成绩,求考第k名学生的学号和成绩. 输入第一行有两个整数,分别是学生的人数n(1≤n≤100),和求第k名学生的k(1≤k≤n). ...

  7. ubuntu下安装UltraEdit

    在windows下常年使用UltraEdit来查看log,现在突然切换到ubuntu下,系统自带的Text Editor相当不适应:只有自己安装了. 首先,需要下载安装包,可以去:http://www ...

  8. shell 提取字符串

    记录一下: 我们可以用  ${ }  分别替换获得不同的值: file=/dir1/dir2/dir3/my.file.txt ${file#*/}:拿掉第一条  /  及其左边的字符串:dir1/d ...

  9. linux ssh连接不自动断开

    修改linux服务器ssh配置文件: vim /etc/ssh/ssh_config 修改两处的值为: ClientAliveInterval ClientAliveCountMax 使修改的ssh配 ...

  10. QML与Qt C++ 交互机制探讨与总结

    介绍 QML和 C++对象可以通过,signals,slots和 属性修改进行交互.对于一个C++对象,任何数据都可以通过Qt的 Meta-Object System暴露给QML(何总方法,后面介绍) ...