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

input

n 2<=n<=4000

s1

s2

...

sn

1<=len(si)<=1000

output

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

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

 1 #include <cstdio>
 2 #include <queue>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <cstdlib>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <map>
 9 #include <set>
10 #include <ctime>
11 #include <cmath>
12 #include <cctype>
13 #define MAX 100000
14 #define LL long long
15 #define mod 20071027
16 struct node
17 {
18     int sz;
19     char val;
20     node*ch[2];            //ch[1]兄弟,ch[0]儿子
21     node()
22     {
23         ch[0]=ch[1]=NULL;
24         sz=0;
25     }
26 };
27 char word[1010];
28 int n,cas=1;
29 long long sum;
30 long long insert(char*s,node*u)
31 {
32     long long sum=0,lastsz=u->sz++;
33     for(;*s||*(s-1);s++)
34     {
35         if(!u->ch[0])            //易错,要先把新建的结点连接到父结点才能往下走,否则新建之后父节点无法再读取到该结点
36         {
37             u->ch[0]=new node;
38             u->ch[0]->val=*s;
39         }    
40         for(u=u->ch[0];u->val!=*s;u=u->ch[1])
41         {
42             if(!u->ch[1])
43             {
44                 u->ch[1]=new node;
45                 u->ch[1]->val=*s;
46             }
47         }    
48         sum+=lastsz+u->sz;
49         lastsz=u->sz++;
50     }
51     return sum;
52 }
53 /*//这样可以将父节点的ch和新建的结点绑定起来,传过来的是&root
54 long long insert(char*s,node**u)
55 {
56     long long sum=0,lastsz=(*u)->sz++;
57     for(;*s||*(s-1);s++)
58     {
59         printf("%p\n",u);
60         for(u=&((*u)->ch[0]);(*u)&&(*u)->val!=*s;u=&((*u)->ch[1]));
61         if(*u==NULL)
62         {
63             *u=new node;
64             (*u)->ch[0]=(*u)->ch[1]=NULL;
65             (*u)->val=*s;
66         }
67         sum+=lastsz+(*u)->sz;
68         lastsz=(*u)->sz++;
69     }
70     return sum;
71 }*/
72 void freenode(node*u)
73 {
74     if(u==NULL) return;
75     freenode(u->ch[0]);
76     freenode(u->ch[1]);
77     delete u;
78 }
79 int main()
80 {
81     //freopen("/home/user/桌面/in","r",stdin);
82     while(scanf("%d",&n)==1&&n)
83     {
84         sum=0;
85         node *root=new node;
86         while(n--)
87         {
88             scanf("%s",word);
89             sum+=insert(word,root);
90         }
91         printf("Case %d: %lld\n",cas++,sum);
92         freenode(root);
93     }
94     //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
95     return 0;
96 }
97 
98 my Code
my Code
 1 #include <cstdio>  
 2 #include <cstring>  
 3 #include <iostream>  
 4 #include <algorithm>  
 5 using namespace std;  
 6   
 7 #define repf(i,a,b) for(int i=(a);i<=(b);i++)  
 8 typedef long long ll;  
 9   
10 const int N = 0;  
11 const int MAXNODE = 4000010;  
12   
13 int n, cas;  
14 ll ans;  
15 char str[4001];  
16   
17 struct STrie {  
18     int son[MAXNODE];  
19     int bro[MAXNODE];  
20     int val[MAXNODE];  
21     char ch[MAXNODE];  
22     int sz;  
23   
24     STrie() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; }  
25     void init() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; }  
26     // inline int idx(char c) { return c - 'a'; }  
27       
28     void insert(char *s) {  
29         int len = strlen(s), u = 0, p;  
30         repf (i, 0, len) {  
31             // check the brother of u  
32             for (p = son[u]; p; p = bro[p]) {  
33                 if (ch[p] == s[i])  
34                     break;  
35             }  
36             // cannot find out than insert  
37             if (!p) {  
38                 p = sz++;  
39                 ch[p] = s[i];  
40                 bro[p] = son[u];  
41                 son[p] = 0;  
42                 val[p] = 0;  
43                 son[u] = p;  
44             }  
45             ans += (val[u] - val[p]) * (2 * i + 1);  
46             if (len == i) {  
47                 ans += val[p] * (2 * i + 2);  
48                 val[p]++;  
49             }  
50             val[u]++;  
51             u = p;  
52         }  
53     }  
54 } trie;  
55   
56 int main() {  
57     // ios_base::sync_with_stdio(0);  
58     while (~scanf("%d", &n) && n) {  
59         trie.init();  
60         ans = 0;  
61         repf (i, 0, n - 1) {  
62             scanf("%s", str);  
63             trie.insert(str);  
64         }  
65         printf("Case %d: %lld\n", ++cas, ans);  
66     }  
67     return 0;  
68 } 
copy Code

转载于:https://www.cnblogs.com/cdyboke/p/5015540.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/272670.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

防止SQL注入式攻击的笔记

SQL注入式攻击是指利用设计上的漏洞攻击系统。如果动态生成SQL语句时没有对用户输入的数据进行过滤&#xff0c;便会使SQL注入式攻击得逞。例如用下面的SQL语句判断用户名和密码&#xff1a;txtsql"select * from user_info where userid"&txtuserid &"…

linux输入一个用户看是否在工作,linux下的用户管理详解

linux下的用户管理详解useradd 命令详解添加用户想要对linux下面的帐号了解的话首先必须要了解的4个配置文件[rootlocalhost /]# cat /etc/passwd首先我们需要了解的是用户帐号的配置信息/etc/passwd里面的内容每个字段都以:分割&#xff0c;下面我们详细的看看每个字段的意思r…

Java命令学习系列(零)——常见命令及Java Dump介绍

Java命令学习系列&#xff08;零&#xff09;——常见命令及Java Dump介绍 一、常用命令&#xff1a; 在JDK的bin目彔下,包含了java命令及其他实用工具。  jps:查看本机的Java中进程信息。  jstack:打印线程的栈信息,制作线程Dump。  jmap:打印内存映射,制作堆Dump。  …

优秀程序员的十个习惯

在这个世界上&#xff0c;有数百万的人热衷于软件开发&#xff0c;他们有很多名字&#xff0c;如&#xff1a;软件工程师&#xff08;Software Engineer&#xff09;&#xff0c;程序员&#xff08;Programmer&#xff09;&#xff0c;编码人&#xff08;Coder&#xff09;&…

linux下jmap 内存命令,Linux下jmap命令查看内存使用

Linux下jmap命令查看内存使用jmap -heap 1234(1234为进程号)jmap是JDK自带的一个工具&#xff0c;非常小巧方便&#xff0c;其支持参数如下&#xff1a;-heap打印heap空间的概要&#xff0c;这里可以粗略的检验heap空间的使用情况。例&#xff1a;jmap -heap 12345输出&#xf…

BZOJ3144: [Hnoi2013]切糕

题目&#xff1a;http://www.lydsy.com/JudgeOnline/problem.php?id3144 把每一条z轴都拿出来&#xff0c;s->(x,y,1),cf[x][y][1];(x,y,k)->(x,y,k1),cf[x][y][k];(x,y,r)->t,cinf 然后对于四联通的点&#xff0c;(x,y,z)->(x,y’,z-d) 似乎这叫经典的最小割模型…

如何通俗地解释 C、C++、C#、Java、JavaScript、HTML、Python的用处

世界上本来没有计算机&#xff0c;工程师创造了它。为了让告诉计算机需要做什么事情&#xff0c;工程师发明了程序设计语言。简单粗暴的编程&#xff1a;C语言&#xff1a;用来学编程&#xff1b;C语言&#xff1a;用来使劲儿学编程&#xff1b;C#&#xff1a;用来在windows操作…

安卓linux交叉编译,Linux Ubuntu下用Android NDK 生成独立交叉编译链

本文主要介绍使用Android NDK生成独立交叉编译链&#xff0c;然后使用独立交叉编译链编译Android程序下载NDK下载与自己操作系统相吻合的版本 下载地址解压到安装目录(如~/myndk):tar -zxvf android-ndk-r14b-linux-x86_64将NDK的根目录生成一个环境变量打开~/.bashrcw文件&…

数据结构——各排序算法的比较

1.从时间复杂度比较   从平均时间复杂度来考虑&#xff0c;直接插入排序、冒泡排序、直接选择排序是三种简单的排序方法&#xff0c;时间复杂度都为O(n2)&#xff0c;而快速排序、堆排序、二路归并排序的时间复杂度都为O(nlog2n)&#xff0c;希尔排序的复杂度介于这两者之间。…

将c程序移植到linux,各位大侠:我把原来在linux运行的c程序移植到HPUNIX上出现了错误...

各位大侠&#xff1a;我把原来在linux运行的c程序移植到HPUNIX上出现了错误(2012-04-11 00:43:47)标签&#xff1a;linuxc程序杂谈各位大侠&#xff1a;我把原来在linux运行的c程序移植到HP_UNIX上出现了错误makefileCC aCC -AA W829 DD64 DAportable-I/ods/app/oracle/produc…

数据库学习建议之提高数据库速度的十条建议

很多网站的重要信息都是保存在数据库中的&#xff0c;用户通过提交访问数据库来获取用户信息。如果数据库速度非常的快&#xff0c;有助于节省服务器的资源&#xff0c;在这篇文章中&#xff0c;我收集了十个优化数据库速度的技巧。0. 小心设计数据库第一个技巧也许看来理所当然…

Java中数据类型的取值范围

整数数据类型的取值范围 我们都知道计算机的底层是二进制&#xff0c;也知道不同的整数类型存储值的范围不同&#xff0c;可这些数值在计算机底层是怎样存储的呢&#xff1f;数值范围又是怎么计算出来的呢&#xff1f; 下面以java来进行举例&#xff1a; byte 1个字节 (8bit…

linux的cpu信息怎么理解,理解Linux下的CPU信息:lscpu cpuinfo

通过lscpu命令&#xff0c;可以看到CPU的一些基本信息。如下所示&#xff0c;可以很清楚的看到这台服务器使用两个物理socket&#xff0c;每个socket上有6个core&#xff0c;每个core上有两个线程(超线程)&#xff0c;所以一共有2 * 6 * 2 24个逻辑CPU。Architecture: x86_64C…

如何降低SQL语句复杂度

SQL语句复杂度的优化就是在结果正确的前提下&#xff0c;将复杂、难以维护的SQL语句拆分成独立、易懂的SQL片段&#xff0c;当然也要充份利用索引&#xff0c;减少表描的I/O次数&#xff0c;尽量避免表搜索的发生。下面介绍降低SQL语句复杂度的几个建议1、动态查询语句一些应用…

提高程序员工作效率的11个技巧

“吃苦耐劳”真的是优良品质吗&#xff0c;与你怎么做相比&#xff0c;老板们应该更关心你做了什么、达到的效果。所以&#xff0c;效率&#xff0c;还是效率&#xff0c;希望这些实用小技巧对大家有所帮助。1、两分钟法则如果一件事可以在两分钟内完成&#xff0c;比如回复邮件…

tq3358 linux 串口驱动编程,TQ335x——spidev驱动的生成

kernel&#xff1a;CD盘的kernel3.2包环境&#xff1a;vmware10&#xff0c;ubuntu14.04修改的部分&#xff1a;arch/arm/mach-omap2/board-am335xevm.c文件中static struct spi_board_info am335x_spi1_slave_info[] {{.modalias "smb380",.platform_data &A…

Linux下显示ip所属位置

在linux下&#xff0c;要是网络出现延迟&#xff0c;通常我们需要分析自己到对端的服务器的网络环境 1 例&#xff1a;ping www.baidu.com 2 traceroute www.baidu.com 通过分析来确定大概是什么问题&#xff0c;可当我们去跟踪某个ip的时候不知道来源&#xff0c;假如每一个…

C#程序集相关的概念

程序集包含&#xff1a;类型元数据&#xff08;描述在代码中定义的每一类型和成员&#xff0c;二进制形式&#xff09;。程集元数据&#xff08;程序集清单、版本号、名称等&#xff09;、IL代码&#xff08;这些都被装在exe或dll中&#xff09;、资源文件。每个程序集都有自己…

linux+删除乱码的文件,linux 下删除乱码文件-乾颐堂

在linux下删除文件&#xff0c;遇到特殊字符是一件非常头疼的事情。1. 如果文件名带 ‘-’ 或者‘--’这样的字符删除办法为&#xff1a;rm -- 文件名如文件名为&#xff1a;-pythontab.tgz如果用普通方法去删除&#xff1a;1rm -pythontab.tgz结果错误&#xff1a;rm: invalid…

程序员如何保护自己的颈椎

我们程序员天天对着电脑&#xff0c;眼睛&#xff0c;颈椎等等&#xff0c;都会落下不少的职业病。来说说怎么治疗自己的颈椎病。1、颈椎病是怎么产生的形成颈椎病的核心原因是&#xff1a;不良生活习惯我们身体的绝大部分疾病都是来自不良的生活习惯&#xff0c;生活习惯不改&…