【NOIP2017提高A组模拟9.14】生命之树 (dsu on tree+trie)

TreeOfLife:生命之树 生命之树 基于现代分类学的生物进化树编辑程序。 技术要点 树与图的增删改查其及其序列化/反序列化 文件封装与版本控制 语义分析与模糊搜索 树与图操作,搜索以及序列化/反序列化的性能优化 版本跟踪 里程碑10(开发中) 即将实现图形化的演进树。 里程碑9(版本1.0.915.1000.M9.210129-2000) 原始数据结构由N叉树替换增加有向图,实现并系群,复系群的编辑与存储,版本控制首次获得验证,删除的类群将自动从搜索结果中移除,更新中文名由自动改为提示。 里程碑8(版本1.0.812.1000.M8.210108-2100) 实现模糊搜索功能,纯文本演化树替换仅显示当前类群附近的部分,选择类群和编辑类群时将同步更新演化树,编辑类群分级时将自动更新中文名。 里程碑7(版本1.0.708.1000.M7.201230-2100) 实现基本的搜索功能和UI。 里程碑6(版本1.0 立即下载

Description:

这里写图片描述
1<=n<=105,|S|<=5∗105

题解:

这是一道树上启发式的题目,也算是我做得树上启发式的第一题,这次比赛一下出现了两题树上启发式,都不会,让人无语。

看到xor,马上拆位,这个都是老套路了。
对于一个点u,把它和它的子树的字符串全部一次丢到一个trie里,因为已经拆了位,随便维护一下就可以求出答案。

但是我们知道这样暴力是很慢的,复杂度易得。

利用启发式可以把暴力的复杂度优化。

大概流程如下:
对于一个点x,先计算其轻儿子的答案,做完以后,全局的trie是清空的。
接着计算其重儿子的答案,注意此时重儿子的所有子树的节点的字符串是在trie里。
接着再把x的除重儿子子树外的所有节点加入trie,x也要加进trie里。
这样x的子树的答案就已经计算出来了。
如果x是其父亲节点的重儿子,保留当前的trie,否则清空trie。

我们可以分析一下复杂度:
一个点被加入trie的次数就是它到根的路径上的轻重链数的总和,有加入才有删除。
所以复杂度是:O(|S|∗log n)

Code:

#include<cstdio>
#include<cstring>
#define ll long long
#define fo(i, x, y) for(int i = x; i <= y; i ++)
using namespace std;

const int N = 500005;

char s[N], S[N];

int a2[17], w;
int n, x, y, a[N][17], l[N], r[N];
int final[N], tot;
struct edge {
    int to, next;
}e[N * 2];
int fa[N], bz[N], siz[N], son[N];
int next[N][26], tt = 1, root = 1;
ll ans[N], ans2[N], sm[N][2];

void link(int x, int y) {
    e[++ tot].next = final[x], e[tot].to = y, final[x] = tot;
    e[++ tot].next = final[y], e[tot].to = x, final[y] = tot;   
}

void dg(int x) {
    bz[x] = 1;
    siz[x] = 1;
    for(int i = final[x]; i; i = e[i].next) {
        int y = e[i].to; if(bz[y]) continue;
        fa[y] = x; dg(y); siz[x] += siz[y];
        son[x] = siz[y] > siz[son[x]] ? y : son[x];
    }
    bz[x] = 0;  
}

ll Insert(int x) {
    int y = root; ll sum = 0;
    fo(i, l[x], r[x]) {
        int c = s[i] - 'a';
        if(next[y][c] == 0) next[y][c] = ++ tt;
        y = next[y][c];
        sum += sm[y][!a[x][w]] * a2[w];
        sm[y][a[x][w]] ++;
    }
    return sum;
}

ll dfs(int x) {
    bz[x] = 1;
    ll sum = Insert(x);
    for(int i = final[x]; i; i = e[i].next) {
        int y = e[i].to; if(bz[y]) continue;
        sum += dfs(y);
    }
    bz[x] = 0;
    return sum;
}

void dg2(int x) {
    bz[x] = 1;
    for(int i = final[x]; i; i = e[i].next) {
        int y = e[i].to; if(bz[y] || y == son[x]) continue;
        dg2(y);
    }
    if(son[x] != 0) dg2(son[x]), ans[x] += ans[son[x]];
    for(int i = final[x]; i; i = e[i].next) {
        int y = e[i].to; if(bz[y] || y == son[x]) continue;
        ans[x] += dfs(y);
    }
    ans[x] += Insert(x);
    if(x != son[fa[x]]) {
        fo(i, 1, tt) memset(next[i], 0, sizeof(next[i])), sm[i][0] = sm[i][1] = 0;
        tt = 1;
    }
    bz[x] = 0;
}

int main() {
    freopen("tree.in", "r", stdin);
    freopen("tree.out", "w", stdout);
    scanf("%d", &n);
    fo(i, 1, n) {
        scanf("%d", &x);
        fo(j, 0, 16) a[i][j] = x & 1, x /= 2;
    }
    fo(i, 1, n) {
        scanf("%s", S + 1);  int len = strlen(S + 1);
        l[i] = r[i - 1] + 1; r[i] = r[i - 1] + len;
        fo(j, l[i], r[i]) s[j] = S[j - l[i] + 1];
    }
    fo(i, 1, n - 1) {
        scanf("%d %d", &x, &y);
        link(x, y);
    }
    dg(1);
    a2[0] = 1; fo(i, 1, 16) a2[i] = a2[i - 1] * 2;
    for(w = 0; w <= 16; w ++) {
        dg2(1);
        fo(i, 1, n) ans2[i] += ans[i], ans[i] = 0;
    }
    fo(i, 1, n) printf("%lld\n", ans2[i]);
}
mysql笔记:23. 在Mac上安装与卸载MySQL MySQL对Mac电脑的适配十分强大,再加上Mac本身就是Unix操作系统演化而来的,所以在Mac上安装MySQL的方式有多种。常见的方法有如下三种:DMG、brew、TAR。介绍这些方法前,我们先了解下MySQL安装文件的下载。 阅读详情

相关推荐

sldd数据字典导出为excel

sldd导出为excel

zpfjf的博客 2237

【NOIP2017提高A组模拟9.14】生命之树 trie+启发式合并

题目做法先给这一颗树按照dfs序重新编号,可以发现一个点对它的某一个父亲的贡献就是其与所有编号小于他的点的贡献和,那么我们可以考虑从叶子节点开始,逐步往上计算每一个点的答案 考虑建一些trie树,把二进制的每一个位挂在trie的一些节点上,那么我们就可以在遍历trie的同时把贡献式中的乘法转换为加法 假设我们现在做到点i,那么我们就要把i点的儿子们对应的trie树合并,考虑用启发式合并,在合并的

Marcus 486

SSD盘符漂移导致OSD down场景模拟与恢复

运维团队反馈一个问题,现象是:某个OSD对应的cache分区发生了变化,比如原来cache使用的分区是/dev/sde,后来还是这块盘,但分区信息不知何故,变成了/dev/sdf(产品OSD设备并不是根据分区名称来map,而是根据partlabel),最终的现象是这个OSD down了,没法启动.接到这个现象的反馈后,记录一下这个问题在lab的复现方法。

Gavin Blog 938

【JZOJ5363】【NOIP2017提高A组模拟9.14】生命之树 Trie+启发式合并

题面 45 在比赛中,我只想到了45分的暴力。 对于一个树中点对,相当于在他们的LCA及其祖先加上这个点对的贡献。 那么这个可以用dfs序+树状数组来维护。 100 想法 我想到了可能要用trie树来维护这个字符串的公共前缀。 然后这就面临了两个很严重的问题。 1.我对于每个子树都要建一个trie,所以这是\(O(n^2)\)的复杂度。 我想到了要合并儿子的信息,但是这个合并似乎是无法存储。 ...

weixin_30569001的博客 255

Cox构建预测模型(5):如何用R语言绘制校准曲线(附全套代码)

这篇文献通过绘制两个模型的DCA曲线来评估模型的临床决策实际需求,一个是列线图模型,包括纳入列线图的全部变量,一个是TNM模型,只纳入TNM分期3个变量。A图是训练集1年、3年、5年患者的总生存期的DCA曲线;B图是训练集1年、3年、5年患者的总生存期的DCA曲线,红色线条代表列线图模型(包括构建模型的10个变量),黄色线条代表TNM模型(仅纳入TNM分期3个变量),两个模型对比,在绘制校准图之前,必须要完成数据的导入、拆分数据集的工作、预测因子的筛选,校准图的绘制是分别在训练集与验证集独立进行的。

qq_37610365的博客 1360

搭建适用于lammps中opls-aa力场的文件流程

现在我已经解决了以上问题,并且通过我的方法可以实现从空白文档到搭建完成以上全部内容,后期只要细心检查即可。需要的data文件最关键是获得相应阴阳离子的mmol文件,因此问题转化为构建一份mmol文件。主要用到的软件及程序:gaussian09,makemol程序(tranal),opls-aa的参数文件。二面角个数:成角原子序号及对应的参数(这里PF6的结构没有二面角,所以为0)参考文献个数:文献名(空够行数即可,这些是给自己的备忘))和自身体系对应的参考文献,修改或填入对应的参数即可。

baguette的博客 2887

启发式合并/dsu on tree 姿势

Dsu on Tree一场比赛有两道,好tm巧啊Problem 1这种方法其实就是通过性质优化的暴力。遍历时轻边优先。 首先肯定是拆位了,然后可以用trie维护一下某颗子树内的点的串,很容易统计答案。 (具体要看题解了) 但是暴力加/删点会T,就要用dot了。 发现计算完一个儿子的答案之后,整颗子树都被添加到了trie中。但如果要继续做其他儿子所以要清空trie. 有一颗子树是可以不用清空

一位蒟蒻的小博客 497

STM32 HAL库定时器中断实现步进电机S型加减速控制与脉冲精准计数

本文详细介绍了如何使用STM32 HAL库定时器中断实现步进电机的S型加减速控制与脉冲精准计数。通过CubeMX配置定时器、计算PSC和ARR值,并结合S型曲线算法,实现平滑启停和精准定位。文章还提供了脉冲计数方案和常见问题排查技巧,帮助开发者优化步进电机控制性能。

weixin_29189363的博客 373

jzoj5363【NOIP2017提高A组模拟9.14】生命之树 trie+启发式合并

题意:有一颗树,每个点有一个权值和一个字符串,要求计算出以每个点的子树的贡献,贡献的定义是两个点权值的xor*两个点字符串的lcp。n<=1e5其实这题我第一眼就想到trie,但是我trie基本上没做过多少题,不会xor统计的那种科技(这个太基础了吧喂),然后就异想天开用了个SA,结果爆炸,调了半天调不出来,心情复杂。正解是trie合并。开两颗trie,一颗记录lcp,一颗记录每个子树内有多少个点的

老臣 411

obisidian插件之【templater】模板的中文说明书

Templater 是一种模板语言,可让您将变量和函数结果插入到笔记中。它还允许您执行操作这些变量和函数的 JavaScript 代码。使用 Templater,您将能够创建强大的模板来自动执行手动任务。

m0_55795604的博客 1万+

基于STM32的智能血氧、心率、体温、血压监测系统

摘要:本文设计了一款基于STM32F103C8T6的多功能健康监测系统,可实时检测血氧、心率、体温和血压四项生理参数。系统集成MAX30102、DS18B20等传感器模块,采用OLED显示和蓝牙无线传输技术,实现一键血压测量、阈值报警及手机APP数据管理功能。硬件设计包含传感器采集、电源管理、显示报警等模块;软件采用模块化架构,实现数据采集处理、蓝牙通讯等功能。测试表明系统测量准确可靠,为家庭健康监测提供了便携解决方案。未来可扩展更多监测参数和智能分析功能。

3254968421的博客 771

jzoj5363-[NOIP2017提高A组模拟9.14]生命之树【启发式合并,Trie】

正题 题目大意 nnn个点的一棵树,每个节点有一个值valvalval和一个字符串SSS。对于每个点求∑x∈decp∑y∈decp(x<y)(valx xor valy)∗∣LCP(Sx,Sy)∣\sum_{x\in dec_p}\sum_{y\in dec_p(x<y)}(val_x\ xor\ val_y)*|LCP(S_x,S_y)|x∈decp​∑​y∈decp​(x<y)∑​(valx​ xor valy​)∗∣LCP(Sx​,Sy​)∣

QuantAsk 417

YOLOv8【第一章:基础入门篇·第1节】一文搞定,核心架构深度解析与环境配置!

🏆 本文收录于 《YOLOv8实战:从入门到深度优化》 专栏,该专栏专注于分享我在YOLOv8目标检测模型中的实战经验,涵盖从入门基础到深度优化的全方位解决方案。无论你是计算机视觉的新手,还是具有多年深度学习经验的专家,本专栏都将为你提供高效、可复现的技术方案,助你掌握YOLOv8的核心技术,提升目标检测性能,突破瓶颈,优化模型,并加速项目开发🚀!

**My Coding Family** 2104

07-29 NOIP模拟测试10

A. 辣鸡(ljh) 看到这题时有点虚,没选化学啊喂。 一开始一直在想对角线有没有什么性质,然后进死胡同了,去看T2。 回来后,想先qj一下点1,然后发现了块内的贡献可以直接算,一开始我用对角线推的,所以有下面这个鬼畜柿子 ans+=1ll*(1ll*(mi-1)*(mi-2)+(mi-1)*(abs(x-y)+1))*2; 后来发现这种算法十分nc,其实有 $ans_{...

weixin_30360497的博客 190

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

JZOJ6368. 【NOIP2019模拟2019.9.25】质树(tree)

Description 大神 wyp 手里有棵二叉树,每个点有一个点权。大神 wyp 的这棵树是质树,因为 随便找两个不同的点 u, v,只要 u 是 v 的祖先,都满足 u 和 v 的点权互质。 现在你通过偷看了解到了大神 wyp 这棵树的中序遍历的点权值,你想复原出大神 wyp 的树,或者指出不可能。 n<=1e6 Solution 每一次取一个区间中的与其他位置互质的位置为根,如果有...

Deep_Thinking的博客 239

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【NOIP2017提高A组模拟8.23】密码

Description:题解:这肯定是数位dp,十分显然。 首先对n个串建一个AC自动机,这样我们就可以表示出当前dp的状态了。 设fi,j,k,0/1f_{i ,j, k,0/1}表示从高往低已经确定了前i个位,匹配数为j,包含当前第i位的后缀走到了AC自动机的第j位,是否顶满。 转移就相当于在AC自动机通过fail跳,预处理一下就行了。 可以维护一个数组表示在AC自动机上的第i个点,这个

Cold_Chair的博客 514

【NOIP2017提高A组模拟8.22】密码

Description: 1<=n<=1e1000, 1 <= p <= 1e9, 1 <= k <= 1e9题解:题目要求: ∑ni=1∑ij=1[Cji含有的p的幂次>=k]\sum_{i = 1} ^n \sum_{j = 1} ^ i [C_{i}^j 含有的p的幂次 >= k] 我们知道有库默尔定理,这是这道题的基础。 库默尔定理: [Cji+j含有的p的幂次=i+j在p进制下的

Cold_Chair的博客 647

9.27 脚本

首先第一步vi nginx-running.sh 输入脚本 然后保存退出x  然后挂载安装到root目录下的文件 命令是rpm -ivh /opt/dvd/Packages/zlib-devel-1.2.7-13.el7.x86_64.rpm       rpm -ivh /opt/dvd/Packages/pcre-devel-8.32-12.el7.x86_64.rpm   usera...

yangzhihao6666的博客 208

POJ3630 Phone List Trie解法详解

Phone ListTime Limit: 1000MS Memory Limit: 65536KTotal Submissions: 32591 Accepted: 9459DescriptionGiven a list of phone numbers, determine if it is consistent in the sense that no number is the prefi...

zhwzzhhww的博客 239

bzoj3681 Arietta(dsu on tree+主席树优化建图+网络流)

显然就是个建图最大流。然而边数爆炸。 我们考虑每个节点维护一棵线段树表示子树信息来优化建图,然后边数还是爆炸。 我们再考虑树上建主席树来优化建图,不错,好像可以了,然而子树信息不可减(维护的是权值为x的点的标号)gg这时候我们要用到一种黑科技:dsu on tree! 也就是树上启发式合并。更多参考资料:portal大概就是划分轻重链,然后轻边暴力,这样复杂度就科学了! 具体说下:每个点的线

Icefox的博客 456

【NOIP2017提高A组模拟9.5】心灵治愈

【NOIP2017提高A组模拟9.5】心灵治愈 Description Input Output Sample Input 输入1: 2 3 输入2: 8 8 Sample Output 输出1: 8 输出2: 16711680 Data Constraint Hint 题解 code #include<cstdio> #include<cstdlib> #define ll long long #define R register using namespace std

LSHjr的博客 189

9.27作业

英文字频统计 strHello='''...'''.lower() fo = open('hello.txt', 'r', encoding='utf-8') hello = fo.read() fo.close() print(hello) sep = ''',?''' for ch in sep: strHello = strHello.replace(ch, ''...

weixin_34034670的博客 166

JZOJ5361. 【NOIP2017提高A组模拟9.14】捕老鼠

Description为了加快社会主义现代化,建设新农村,农夫约(Farmer Jo)决定给农庄里的仓库灭灭鼠。于是,猫被农夫约派去捕老鼠。 猫虽然擅长捕老鼠,但是老鼠们太健美了,身手敏捷,于是猫想到了一个绝妙的办法:它决定点燃纯艾条,用烟熏老鼠。 农夫约的农庄里有N 个仓库,排成了一排,编号为1~N。 假设猫在第i 个仓库点燃艾条,烟雾就会充满该仓库,并向左右扩散Ai的距离,接着所有|i-j

lijf2001的博客 521

深度优先搜索之生命之树

1. 问题描述: 在X森林里,上帝创建了生命之树。 他给每棵树的每个节点(叶子也称为一个节点)上,都标了一个整数,代表这个点的和谐值。 上帝要在这棵树内选出一个非空节点集S,使得对于S中的任意两个点a,b,都存在一个点列 {a, v1, v2, ..., vk, b} 使得这个点列中的每个点都是S里面的元素,且序列中相邻两个点间有一条边相连。 在这个前提下,上帝要使得S中的点所对应的整数的和...

二哈 299

JZOJ 【NOIP2017提高A组模拟9.14】捕老鼠

线段覆盖模板,但没怎么打过,这次记住了

LZX_lzx的博客 360

[dsu on tree] BZOJ5040. 未来研究

原题好像是莫队加点技巧O(nn√)O(n\sqrt n),我用莫队加配对堆搞过去了…这题因为区间不交叉,根据包含关系可以建出一棵树,然后就相当于求子树的信息,可以用启发式合并,但是这样可能会多一个log,那么就用dsu on tree了 #include <cstdio> #include <iostream> #include <algorithm>using namespace std;type

CE玩家 538

【NOIP2017提高B组模拟9.7】NYG的动态数点

【NOIP2017提高模拟9.7】NYG的动态数点 Description Input Output Sample Input 输入1: 5 4 6 9 3 6 输入2: 30 15 15 3 30 9 30 27 11 5 15 20 110 25 20 30 15 30 15 25 5 10 20 7 7 16 2 7 7 28 7 Sample Output 输出1: 1 3 2 输出2: 1 13 9 Data Constraint Hint 题解 水题 从左到右枚举除数,再向左和向右拓展

LSHjr的博客 233
上一篇: 51nod 1201[整数划分] 1259[整数划分V2] 1597 [有限背包计数问题]
下一篇: 【GDOI2018模拟9.14】通信
Cold_Chair
博客等级 码龄11年 158粉丝 410原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值