UVA - 11732 "strcmp()" Anyone? (trie)
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)的更多相关文章
- UVA 11732 strcmp() Anyone?(Trie的性质)
strcmp() Anyone? strcmp() is a library function in C/C++ which compares two strings. It takes two st ...
- UVA 11732 strcmp() Anyone (Trie+链表)
先两两比较,比较次数是两者相同的最长前缀长度*2+1,比较特殊的情况是两者完全相同时候比较次数是单词长度*2+2, 两个单词'末尾\0'和'\0'比较一次,s尾部'\0'和循环内'\0'比较一次. 因 ...
- UVa 11732 "strcmp()" Anyone? (左儿子右兄弟前缀树Trie)
题意:给定strcmp函数,输入n个字符串,让你用给定的strcmp函数判断字符比较了多少次. 析:题意不理解的可以阅读原题https://uva.onlinejudge.org/index.php? ...
- UVA 11732 strcmp() Anyone? (压缩版字典树)
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- UVa 11732 strcmp()函数(左孩子右兄弟表示法)
#include<iostream> #include<algorithm> #include<string> #include<cstring> #i ...
- UVA 11488-Hyper Prefix Sets(Trie)
题意: 给一个01串的集合,一个集合的幸运值是串的个数*集合中串的最大公共前缀 ,求所有子集中最大幸运值 分析: val[N]表示经过每个节点串的个数求幸运值 求就是每个节点值*该节点的深度 搜一遍树 ...
- UVA 11732 - strcmp() Anyone?(Trie)
UVA 11732 - strcmp() Anyone? 题目链接 题意:给定一些字符串,要求两两比較,须要比較的总次数(注意.假设一个字符同样.实际上要还要和'\0'比一次,相当比2次) 思路:建T ...
- 左儿子右兄弟Trie UVA 11732 strcmp() Anyone?
题目地址: option=com_onlinejudge&Itemid=8&category=117&page=show_problem&problem=2832&qu ...
- CJOJ 1071 【Uva】硬币问题(动态规划)
CJOJ 1071 [Uva]硬币问题(动态规划) Description 有n种硬币,面值分别为v1, v2, ..., vn,每种都有无限多.给定非负整数S,可以选用多少个硬币,使得面值之和恰好为 ...
随机推荐
- Marriage Match IV HDU - 3416(最短路 + 最大流)
题意: 求有多少条最短路 解析: 正着求一遍最短路 得dis1 反着求一遍得 dis2 然后 遍历所有的边 如果 dis1[u] + dis2[v] + w == dis1[B], 则说明这是一 ...
- Ionic开发遇到的坑整理
1.修改tabs页的图标,关键是 outline 在使用自定义图标的时候,需要修改 /theme/icons.scss 文件,但是如何定义选中前后的分别使用哪个图标呢 定义选中前的状态 .ion-io ...
- NODE&NPM
Awesome npm packages 更新版本: Mac/Linux:npm install -g n && n stable (默认安装目录为:usr/local/local/n ...
- PSR-4 规范实例讲解 -- php 自动加载
参考 参考文档:https://www.kancloud.cn/thinkphp/php-fig-psr/3144 参考实例:https://github.com/php-fig/fig-standa ...
- HNOI2017 抛硬币 (FakeBeng)
除了队长快跑外最难的题吧. 除了需要写\(exLucas\)之外,还教会了我大量的卡常技巧. 首先\(70\)分就是个直接按题意模拟,易得\(ans=\sum_{j=0}^{b} C_{b}^{j}\ ...
- 【题解】 bzoj3555: [Ctsc2014]企鹅QQ (字符串Hash)
题面戳我 Solution 我们分析题意,他要求的是两个字符串只有一个字符不同,然后我们再看长度\(L \leq 200\),显然我们就可以把每一位删除后\(Hash\),然后判断相同个数即可 我一开 ...
- 【Luogu3732】[HAOI2017]供给侧改革(Trie树)
[Luogu3732][HAOI2017]供给侧改革(Trie树) 题面 洛谷 给定一个纯随机的\(01\)串,每次询问\([L,R]\)之间所有后缀两两之间的\(LCP\)的最大值. 题解 一个暴力 ...
- HGOI 20190310 题解
/* 又是又双叒叕WA的一天... 我太弱鸡了... 今天上午打了4道CF */ Problem 1 meaning 给出q组询问,求下列函数的值$ f(a) = \max\limits_{0 < ...
- GCD HDU - 1695(容斥原理)
要求从满足gcd(x, y) = k的对数,其中x属于[1, n], y属于[1, m] gcd(x, y) = k ==>gcd(x/k, y/k) =1 x/k属于[1, n/k], y/k ...
- CodeForces 407C 组合数学(详解)
题面: http://codeforces.com/problemset/problem/407/C 一句话题意:给一个长度为n的序列g,m次操作,每次操作(l,r,k)表示将g[l]~g[r]的每个 ...