https://vjudge.net/problem/UVA-11732

题意

给定n个字符串,问用strcmp函数比较这些字符串共用多少次比较。

strcmp函数的实现

int strcmp(char *s, char *t)
{
int i;
for (i=; s[i]==t[i]; i++)
if (s[i]=='\0')
return ;
return s[i] - t[i];
}

分析

建trie树,把‘\0’也加进去,记录以每个节点为子树包含的单词节点。

然后dfs计数,遇到单词节点,说明可能存在相同的字符串,于是此时ans+=tot[u]*(tot[u]-1)*dep;

否则就是(2*dep+1)*sum,sum为所有选法。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define ms(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
//#define eps 0.0000000001
#define IOS ios::sync_with_stdio(0);cin.tie(0);
#define random(a, b) rand()*rand()%(b-a+1)+a
#define pi acos(-1)
//const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
const int maxn = * + ;
const int maxm = 4e5 +;
const int mod = ;
const int sigma_size = ; struct Trie{
int head[maxn];// head[i]为第i个结点的左儿子编号
int nxt[maxn];// next[i]为第i个结点的右兄弟编号
char ch[maxn];// ch[i]为第i个结点上的字符
int tot[maxn];// tot[i]为第i个结点为根的子树包含的叶结点总数
int sz;
ll ans;// 答案
void init(){
sz=;
tot[]=head[]=nxt[]=;
}
// 插入字符串s(包括最后的'\0'),沿途更新tot
void insert(char* s){
int u=,v,n=strlen(s);
tot[]++;
for(int i=;i<=n;i++){
// 找字符a[i]
bool f=false;
for(v=head[u];v;v=nxt[v]){
if(ch[v]==s[i]){// 找到了
f=true;
break;
}
}
if(!f){
v=sz++;// 新建结点
tot[v]=;
ch[v]=s[i];
nxt[v]=head[u];
head[u]=v;// 插入到链表的首部
head[v]=;
}
u = v;
tot[u]++;
}
}
// 统计LCP=u的所有单词两两的比较次数之和
void dfs(int dep,int u){
// 叶结点
if(head[u]==) ans+=tot[u]*(tot[u]-)*dep;
else{
int sum=;
for(int v=head[u];v;v=nxt[v]){
sum+=tot[v]*(tot[u]-tot[v]);
// 子树v中选一个串,其他子树中再选一个
}
// 除以2是每种选法统计了两次
ans+=sum/*(*dep+);
for(int v=head[u];v;v=nxt[v])
dfs(dep+,v);
}
}
ll cal(){
ans=;
dfs(,);
return ans;
}
};
Trie trie;
char tmp[];
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("input.txt", "w", stdout);
#endif
int cas=;
int T;
while(~scanf("%d",&T)&&T){
trie.init();
for(int i=;i<T;i++){
scanf("%s",tmp);
trie.insert(tmp);
}
printf("Case %d: %lld\n",cas++,trie.cal());
}
return ;
}

UVA - 11732 "strcmp()" Anyone? (trie)的更多相关文章

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

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

  2. UVA 11732 strcmp() Anyone (Trie+链表)

    先两两比较,比较次数是两者相同的最长前缀长度*2+1,比较特殊的情况是两者完全相同时候比较次数是单词长度*2+2, 两个单词'末尾\0'和'\0'比较一次,s尾部'\0'和循环内'\0'比较一次. 因 ...

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

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

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

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

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

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

  6. UVA 11488-Hyper Prefix Sets(Trie)

    题意: 给一个01串的集合,一个集合的幸运值是串的个数*集合中串的最大公共前缀 ,求所有子集中最大幸运值 分析: val[N]表示经过每个节点串的个数求幸运值 求就是每个节点值*该节点的深度 搜一遍树 ...

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

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

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

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

  9. CJOJ 1071 【Uva】硬币问题(动态规划)

    CJOJ 1071 [Uva]硬币问题(动态规划) Description 有n种硬币,面值分别为v1, v2, ..., vn,每种都有无限多.给定非负整数S,可以选用多少个硬币,使得面值之和恰好为 ...

随机推荐

  1. Sudoku POJ - 3076

    Sudoku Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 5769   Accepted: 2684 Descripti ...

  2. anaconda4.2.0

    上改完cv2那个文件夹后,发现在使用导入的cv2中的方法时没有代码提示,于是搞啊搞,终于让我搞坏了mmp,这也太脆弱了. 无奈组装了一个全新的方法 过程比较坎坷也就没怎么记录 我的版本是选择最后一个o ...

  3. [luogu3878][TJOI2010]分金币【模拟退火】

    题目描述 现在有n枚金币,它们可能会有不同的价值,现在要把它们分成两部分,要求这两部分金币数目之差不超过1,问这样分成的两部分金币的价值之差最小是多少? 分析 根据模拟退火的基本套路,先随机分两堆金币 ...

  4. [NOI2005]月下柠檬树(计算几何+积分)

    题目描述 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔 地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树旁,独自思 索着人生的哲理. 李哲是一个喜爱思考的孩子,当他看 ...

  5. [ZJOI2007]时态同步(dfs+贪心)

    小Q在电子工艺实习课上学习焊接电路板.一块电路板由若干个元件组成,我们不妨称之为节点,并将其用数字1,2,3.进行标号.电路板的各个节点由若干不相交的导线相连接,且对于电路板的任何两个节点,都存在且仅 ...

  6. hdu 1238 Substrings(kmp+暴力枚举)

    Problem Description You are given a number of case-sensitive strings of alphabetic characters, find ...

  7. thinkphp5中__PUBLIC__的使用

    在使用thinkphp5.1开发的时候遇到设置__PUBLIC__无法生效的问题.这次的版本升级有比较大的改动,很多写法已经被更改,下面说下怎么去解决这个问题. 工具/原料   phpstorm ln ...

  8. hdu 2149 (巴什博奕)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2149 Problem Description 虽然不想,但是现实总归是现实,Lele始终没有逃过退学的 ...

  9. 三小时学会Kubernetes:容器编排详细指南

    三小时学会Kubernetes:容器编排详细指南 如果谁都可以在三个小时内学会Kubernetes,银行为何要为这么简单的东西付一大笔钱? 如果你心存疑虑,我建议你不妨跟着我试一试!在完成本文的学习后 ...

  10. 被addPropertyChangeListener("...",this)差点搞崩溃

    以前常用的是addPropertyChangeListener(this)方法 记得有一天我发现还有另一种写法: addPropertyChangeListener(String propertyNa ...