当前位置: 首页 > news >正文

LG10333 [UESTCPC 2024] 打字 题解

LG10333 [UESTCPC 2024] 打字 题解

给定一颗 \(n\) 个节点的 trie 树,以 \(1\) 号节点为根,其余每个节点到父亲的边上都有一个字符,且父亲相同的节点到父亲的边上的字符互不相同。从根到每个节点的路径都代表一个单词,这个单词由路径上的字符顺序拼接而成。在每个节点 \(i\) 处有一个权值 \(c_i\),表示该节点所代表的单词需要写出的次数。

你有一个 cache,可以选择任意个单词放在 cache 里面。写单词时,每写一个字符需要花费 \(a\) 的代价。当写出一个完整的单词时,就可以选择结束当前单词,转而拼写下一个单词。而 cache 会根据当前已经写出的字符,把 cache 中以这一部分字符为前缀且字典序最小的单词提示出来。此时你可以花费 \(b\) 的代价直接写出这个单词,并结束当前单词的拼写,转而拼写下一个单词。注意一个字符串本身也看作它自己的前缀。

求完成 trie 树上所有单词的拼写所需的最小代价。

几乎全部参考这篇题解,主要是好久没写李超树和这种斜率的题了,于是单独开一篇记录一下。

首先还是要读懂题目(这个入一开始就没读懂)。这个的意思不是说拼写完成一个单词后可以根据这个单词提示,而是,每次单词的拼写是独立的,只不过拼写一个单词的过程中,可以先花费 \(a\times len\) 写一段前缀,再花费 \(b\) 直接提示出来。

还是正难则反:如果不使用 cache,总花费是 \(a\times c_i\times dep_i\);考虑怎样使用 cache 减少尽可能多的花费。

假设已经选定好了 cache,将 cache 中的字符串按字典序排好并标号(这个顺序显然也等价于 dfs 序),设第 \(i\) 个字符串对应 trie 树上的节点为 \(u(i)\),则对于第 \(i\) 个字符串减少的花费为

\[[(dep_{i}-dep_{\text{lca}(u(i),u(i-1))}-1)a-b]c_i \]

可以写成转移的形式,便于形成字符串按字典序依次转移的印象

\[dp_i=dp_{i-1}+[(dep_i-dep_{\text{lca}}-1)a-b]c_i \]

假设当前我们将点 \(u\) 加入 cache,需要从 dfs 序小于 \(u\) 的点 \(v\) 转移过来。

\[dp_u=\max_{dfn_v<dfn_u} dp_v+[(dep_u-dep_{\text{lca}(u,v)}-1)a-b]c_u \]

考虑去掉 \(\text{lca}\),令 \(f\) 为点 \(u\) 的一个祖先,\(g_f=\max_{\text{lca}(u,v)=f} dp_v\),自然有

\[dp_u=\max_f g_f+[(dep_u-dep_f-1)a-b]c_u \]

这个 \(g_f\) 的定义看起来很唬人,但实际上你会发现这相当于遍历整棵 trie 树时,每个 \(f\) 完全访问过的子树中节点 \(dp\)\(\max\),即包含当前点 \(u\) 的子树和 dfs 序在之后的子树不包括在内。

然后对于这个式子就可以写成直线的形式

\[dp_u=\max_f\{-(dep_f+1)a\times c_u+g_f \}+dep_u a\cdot c_u-b\cdot c_u \]

每次当 \(g_f\) 的值有更新时将 \(y=-(dep_f+1)c_ux+g_f\) 这条直线加入李超线段树,查询 \(c_u\) 时的最大值即可。

可能会有疑问,当一个点 \(v\) 不是 \(u\) 的祖先时,我们也会查询到 \(v\) 对应的直线。但这并不影响,因为 \(f=\text{lca(u,v)}\) 一定也会在李超树中,且 \(g_f\geq g_v,dep_f<dep_v\),一定会优先取到 \(f\)

具体实现见代码。

const int R=10000;
int n;
ll A,B,c[N],dp[N],g[N],ans;
int dep[N];
vector<int>tar[N];
struct sgline{ll k,b;
}lin[N];int tot;
int bel[N<<2];
#define ls p<<1
#define rs p<<1|1
#define mid ((l+r)>>1)
inline ll hei(int id,ll L){return lin[id].k*L+lin[id].b;}
void modify(int p,int l,int r,int id){if(hei(id,mid)>hei(bel[p],mid))swap(bel[p],id);if(hei(id,l)>hei(bel[p],l))modify(ls,l,mid,id);if(hei(id,r)>hei(bel[p],r))modify(rs,mid+1,r,id);
}
void update(int p,int l,int r,int L,int R,int id){if(L<=l&&r<=R)return modify(p,l,r,id),void();if(L<=mid)update(ls,l,mid,L,R,id);if(R>mid)update(rs,mid+1,r,L,R,id);
}ll query(int p,int l,int r,int L){ll tmp=hei(bel[p],L);if(l==r)return tmp;if(L<=mid)tmp=max(tmp,query(ls,l,mid,L));else tmp=max(tmp,query(rs,mid+1,r,L));return tmp;
}
inline void add(ll k,ll b){lin[++tot].k=k;lin[tot].b=b;modify(1,0,R,tot);
}void dfs(int u){dp[u]=query(1,0,R,c[u])+dep[u]*A*c[u]-B*c[u];g[u]=dp[u];//子树maxadd(-(dep[u]+1)*A,g[u]);for(auto v:tar[u]){dep[v]=dep[u]+1;dfs(v);if(g[v]>g[u]){g[u]=g[v];add(-(dep[u]+1)*A,g[u]);}}
}int main(){scanf("%d%lld%lld",&n,&A,&B);for(int i=1;i<=n;++i){scanf("%lld",&c[i]);int x;scanf("%d",&x);for(int j=1;j<=x;++j){int v;scanf("%d",&v);tar[i].push_back(v);}}dep[1]=0;dfs(1);for(int i=2;i<=n;++i){ans+=A*dep[i]*c[i];}ans-=g[1];printf("%lld\n",ans);return 0;
}
http://www.jsqmd.com/news/772471/

相关文章:

  • 不只是编译:用Chromium源码在VS 2022里搭个专属调试环境,给浏览器功能动手术
  • Arm Cortex-A78AE调试寄存器架构与汽车电子应用
  • MAA明日方舟助手:终极自动化指南,告别重复劳动!
  • CodingBuddy:提升开发效率的智能编程伙伴插件系统
  • 借助Taotoken的API Key管理与审计日志功能加强项目安全
  • 【UNet 改进 | 注意机制篇】UNet引入STA超级令牌注意力机制(CVPR 2023),稀疏关联采样打破高分计算瓶颈,二次创新
  • FPGA安全设计:IFF机制与比特流防护方案
  • 2026年医美行业正规GEO优化服务商推荐与企业选型专业参考 - 产业观察网
  • AISMM模型落地全链路,手把手教你用技术叙事抢占行业话语权
  • ADSP-21565脱机运行实战:用CCES 2.11.1生成LDR文件并烧写SPI Flash的完整流程
  • FanControl终极指南:免费开源Windows风扇控制软件完全配置教程
  • 如何深度定制GBT7714参考文献样式中的会议论文格式:从“//“到专业呈现
  • 中小企业AISMM落地倒计时:政策补贴窗口期仅剩87天,错过将丧失2025年IT合规准入资格
  • SQL Server 2022部署:Windows环境下安装SQL Server 2022+安装.NET Framework 4.7.2+安装SSMS_20260507
  • 向量检索进阶:混合检索策略与深度重排技术实践
  • GetQzonehistory:让时光倒流,重新遇见过去的自己
  • 如何通过构建 AI 智能体找到工作
  • Livox Mid360 + FAST-LIO2实战:从硬件连接到实时建图,我的机器人SLAM入门踩坑全记录
  • 别再只跑MNIST了!用PyTorch和ResNet50从零搭建自己的花分类器(附完整数据集处理代码)
  • 如何快速搭建高效AI绘画插件生态:ComfyUI Manager完整配置指南
  • 3步学会.NET程序分析工具配置管理:打造你的个性化调试环境
  • LSLib深度解析:掌握《神界原罪》与《博德之门3》MOD开发的三大核心技术难题解决方案
  • 2026年4月专业的脉冲除尘滚振清理筛供货厂家推荐,圆筒清理筛/脉冲除尘滚振清理筛,脉冲除尘滚振清理筛厂商有哪些 - 品牌推荐师
  • MeteoInfo气象数据格式转换终极指南:解决GRIB转ARL的5大常见问题
  • 如何让任何PC游戏都支持本地多人分屏?Universal Split Screen解决方案揭秘
  • 深入TI EDMA3内核:图解PaRAM集与传输链,搞定复杂数据搬移
  • AI原生可视化:GPT-Vis如何让大模型直接生成图表
  • Python包开发提示词库:AI辅助工程化与文档生成实践
  • 别再只问torch.cuda.is_available()了!手把手教你从显卡驱动到PyTorch版本,一步步排查CUDA不可用问题
  • ESXi 8.0 网络配置保姆级教程:从管理网卡到vSwitch,手把手带你避坑