#include<bits/stdc++.h>
using namespace std;
#define ll long longconst int maxnode = 4000 * 1000 + 10;
const int sigma_size = 26;// 字母表为全体小写字母的Trie
struct Trie {int head[maxnode]; // head[i]为第i个结点的左儿子编号int next[maxnode]; // next[i]为第i个结点的右兄弟编号char ch[maxnode];  // ch[i]为第i个结点上的字符int tot[maxnode];  // tot[i]为第i个结点为根的子树包含的叶结点总数int sz; // 结点总数long long ans; // 答案void clear() { sz = 1; tot[0] = head[0] = next[0] = 0; } // 初始时只有一个根结点// 插入字符串s(包括最后的'\0'),沿途更新totvoid insert(const char *s) {int u = 0, v, n = strlen(s);tot[0]++;for(int i = 0; i <= n; i++) {// 找字符a[i]bool found = false;for(v = head[u]; v != 0; v = next[v])if(ch[v] == s[i]) { // 找到了found = true;break;}if(!found) {v = sz++; // 新建结点tot[v] = 0;ch[v] = s[i];next[v] = head[u];head[u] = v; // 插入到链表的首部,免除对兄弟链的遍历,这里兄弟先后无关系head[v] = 0;}u = v;tot[u]++;}}// 统计LCP为u的所有单词两两的比较次数之和void dfs(int depth, int u) {if(head[u] == 0) // 叶结点ans += tot[u] * (tot[u] - 1) * depth;//叶子节点的tot反映了有多少个自己else {int sum = 0;for(int v = head[u]; v != 0; v = next[v])sum += tot[v] * (tot[u] - tot[v]); // 子树v中选一个串,其他子树中再选一个ans += sum / 2 * (2 * depth + 1); // 除以2是每种选法统计了两次for(int v = head[u]; v != 0; v = next[v])dfs(depth+1, v);}}// 统计long long count() {ans = 0;dfs(0, 0);return ans;}
};const int maxl = 1000 + 10;   // 每个单词最大长度int n;
char word[maxl];
Trie trie;int main() {int kase = 1;while(scanf("%d", &n) == 1 && n) {trie.clear();for(int i = 0; i < n; i++) {scanf("%s", word);trie.insert(word);}printf("Case %d: %lld\n", kase++, trie.count());}return 0;
}

注释了一波lrj的代码。。

与前文的Trie树不同,左孩子右兄弟树的每一个节点的大小没有sigma_size那么大

这就大大节省了空间:通过时间上兄弟间的遍历链条关系来节约空间,整个结构没有无用节点

暂且能掌握这种树的用法咱就算达到目的了吧orz

转载于:https://www.cnblogs.com/Drenight/p/8611324.html

strcmp() Anyone? UVA - 11732 左孩子右兄弟Trie/计数相关推荐

  1. 辅助类BinaryTreeNodeLeftChildRightSibling(左孩子右兄弟,二叉树结点)

    辅助类BinaryTreeNodeLeftChildRightSibling(左孩子右兄弟,二叉树结点) template<typename T> class BinaryTreeNode ...

  2. java实现家庭关系图_左孩子右兄弟二叉树实现家族家谱

    /* Name: 家谱 Description: 本项目对家谱管理进行简单的模拟,以实现查看祖先和子孙个人信息.插入家族成员.删除家族成员等功能. */ #include #include using ...

  3. left-child right-sibling representation of tree - 左孩子右兄弟表示树

    left-child right-sibling representation of tree - 左孩子右兄弟表示树 child-sibling representation, left-child ...

  4. 3422. 左孩子右兄弟

    对于一棵多叉树,我们可以通过 "左孩子右兄弟" 表示法,将其转化成一棵二叉树. 如果我们认为每个结点的子结点是无序的,那么得到的二叉树可能不唯一. 换句话说,每个结点可以选任意子结 ...

  5. 蓝桥杯 左baby右兄弟

    试题: 思路: "左孩子右兄弟"是常见的多叉树转化成二叉树的方法.具体的实现方式是,从第二层最右边的结点开始,将将自己的孩子结点放到左边,左边一位的兄弟放到左边的结点上.对于是多支 ...

  6. 第十二届蓝桥杯省赛A组试题:左儿子右兄弟Java

    [问题描述] 对于一棵多叉树,我们可以通过 "左孩子右兄弟" 表示法,将其转化成一棵二叉树.如果我们认为每个结点的子结点是无序的,那么得到的二叉树可能不唯一.换句话说,每个结点可以 ...

  7. 多叉树的二叉树表示法(左儿子右兄弟)

    在二叉树的基础上,我们可以扩展出任意多个叉的树.即,多叉树.然而,此时又面临着另外一个问题: 当孩子结点无限制时,我们并不知道预先要分配多少个属性,且当仅有少数元素拥有多个子节点时,将会造成大量的空间 ...

  8. 试题H 左Children右兄弟

    (吐槽:为什么不能使用'孩'和'子'这两个字) 题目链接:https://www.lanqiao.cn/courses/2786/learning/?id=280825 题目解析:典型的树形DP 记d ...

  9. UVa 11732 (Tire树) strcmp() Anyone?

    这道题也是卡了挺久的. 给出一个字符串比较的算法,有n个字符串两两比较一次,问一共会有多少次比较. 因为节点会很多,所以Tire树采用了左儿子右兄弟的表示法来节省空间. 假设两个不相等的字符串的最长公 ...

最新文章

  1. Caffe将自己的文件生成lmdb
  2. Spring MVC笔记
  3. sublime text3配置Python2、Python3的编译环境
  4. php多线程模拟请求,浅谈php使用curl模拟多线程发送请求
  5. struts2的namespace的问题
  6. Android官方开发文档Training系列课程中文版:通知用户之大视图通知
  7. 查看JVisualVM查看信息
  8. 老韩思考:一个卖豆腐的能转行IT吗? 你的卖点在哪里?
  9. c语言自动安装软件,VC++(c语言程序下载安装)
  10. 可集成到APP的车架号识别sdk
  11. 开源多云技术平台——Choerodon猪齿鱼发布0.24版本
  12. 企业遇到什么问题一定要用360评估?
  13. 用API网关把API管起来
  14. iOS修复字符串中 有\n 不换行的问题
  15. 数据集特征提取_特征提取和选择
  16. 前端学习与工作中常用网站推荐
  17. 利用7z程序压缩、解压
  18. Python---文件写入
  19. wordpress企业网站主题仿制02-wordpress企业网站首页的仿制
  20. 索尼在线商城的产品会不会更便宜?

热门文章

  1. 有php注入的源码,php注入3_php
  2. 1.3 机器学习基础
  3. python 工作路径
  4. oracle+semijoin,Semi join 与anti join
  5. MathType 在Word中的应用
  6. 用批处理替换文件中的内容
  7. Mysql学习总结(58)——深入理解Mysql的四种隔离级别
  8. Java设计模式学习总结(4)——创建型模式之单例模式
  9. Android学习总结(3)——Handler深入详解
  10. python自动控制库_python PyAUtoGUI库实现自动化控制鼠标键盘