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

P14468 [COCI 2025/2026 #1] 和谐 / Harmonija

洛谷

和同学拼好解拼出了一个轻松爆标的做法,时间复杂度 \(O(q\log n+nk^3\alpha(n))\),实测洛谷上最慢不超过 0.5s,并且很短。

首先设计矩阵,容易想到直接设计 \(5\times 5\) 的矩阵转移,每个状态表示多了几个红色或多了几个蓝色。

求出每个询问的 LCA 的位置,我直接倍增,所以时间复杂度为 \(O(q\log n)\),把询问记录在 LCA 上,离线处理。

然后维护一个并查集,将矩阵作为权值进行维护,对于每个询问采用类似路径压缩的方式维护矩阵。

为了方便维护,我采取的方式是,先不给其它点乘上最顶端的矩阵,让每个除了顶端外的点记录类似前缀的矩阵,这样在压缩时只需要乘上原本的顶端即可求出到新的顶端的矩阵。取出矩阵时如果不是顶端,那么再乘上顶端矩阵即可。

时间复杂度 \(nk^3\alpha(n)\) 实现难度并不高。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,q,a[100005],b[100005],U[100005],V[100005],st[100005][20],dep[100005],fa[100005];
vector<int> e[100005];
long long ans[100005];
struct MT{long long c[5][5];MT(){memset(c,-0x3f,sizeof(c));}MT friend operator*(const MT &a,const MT &b){MT c;for(int i=0;i<5;i++){for(int j=0;j<5;j++){for(int k=0;k<5;k++)c.c[i][j]=max(c.c[i][j],a.c[i][k]+b.c[k][j]);}}return c;}
}I,c1[100005],c2[100005];
vector<int> g[100005];
int LCA(int l,int r){if(dep[l]<dep[r])swap(l,r);for(int i=19;i>=0;i--)if(dep[st[l][i]]>=dep[r])l=st[l][i];if(l==r)return l;for(int i=19;i>=0;i--){if(st[l][i]!=st[r][i]){l=st[l][i];r=st[r][i];}}return st[l][0];
}
void dfs(int p,int f){dep[p]=dep[f]+1;st[p][0]=f;for(int i=1;i<20;i++)st[p][i]=st[st[p][i-1]][i-1];for(int i:e[p])if(i!=f)dfs(i,p);
}
void calc(int x){if(x==fa[x])return;if(fa[x]==fa[fa[x]])return;calc(fa[x]);c1[x]=c1[x]*c1[fa[x]];c2[x]=c2[fa[x]]*c2[x];fa[x]=fa[fa[x]];
}
void dfs2(int p,int f){for(int i:e[p])if(i!=f)dfs2(i,p);MT x;x.c[0][1]=x.c[1][2]=x.c[2][3]=x.c[3][4]=a[p];x.c[1][0]=x.c[2][1]=x.c[3][2]=x.c[4][3]=b[p];c1[p]=c2[p]=I;for(int i:g[p]){int u=U[i],v=V[i];calc(u),calc(v);MT res=(u==fa[u]?c1[u]:c1[u]*c1[fa[u]])*x*(v==fa[v]?c2[v]:c2[fa[v]]*c2[v]);ans[i]=-1e16;for(int j=0;j<5;j++)ans[i]=max(ans[i],res.c[2][j]);}c1[p]=x,c2[p]=x;for(int i:e[p])if(i!=f)fa[i]=p;
}
signed main(){ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);for(int i=0;i<5;i++)I.c[i][i]=0;cin>>n>>q;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++)cin>>b[i];for(int i=1,u,v;i<n;i++){cin>>u>>v;e[u].push_back(v);e[v].push_back(u);}dfs(1,0);for(int i=1,u,v;i<=q;i++){cin>>u>>v;U[i]=u,V[i]=v;g[LCA(u,v)].push_back(i);}for(int i=1;i<=n;i++)fa[i]=i;dfs2(1,0);for(int i=1;i<=q;i++)cout<<ans[i]<<'\n';return 0;
}
http://www.jsqmd.com/news/1403640/

相关文章:

  • 后端巡检从哪开始:盯住错误率、延迟和队列积压
  • 2019年信息安全工程师 上午综合知识真题【整理完整版+答案+详细解析】
  • 2026 太原板材行业深度盘点,千山板材剖析家装选材避坑要点 - 收录优先
  • 宏智树 AI|解锁实证论文新思路,让零散数据转化为学术论证
  • 2026年8月福州外墙漏水维修防水公司推荐,高层高空渗水修缮避坑指南 - 聪居到家
  • 微前端依赖冲突复盘:先保留证据,再隔离版本
  • AI服务容错设计:双层故障处理与四级退避策略实践
  • 【无人机】自主四轴飞行器的模型预测控制附Matlab代码
  • 2026年江苏小型针织大圆机厂家优选:高效规格与精密制造的源头实力解析 - 卓企推荐
  • Azure免费虚拟机零成本创建与避坑指南:12个月B1s实例实战
  • 靠谱的旅行社哪个好
  • 原材料反复波动,工厂供应链降本到底该怎么做?
  • RTP协议解析与实时音视频传输优化实践
  • 爱普生机器人SPEL+编程核心语法与实战应用指南
  • 2026年小型毛皮大圆机厂家供应实力解析:高效编织与精密成型技术观察 - 卓企推荐
  • Arduino智能小车状态机设计:从三模切换理解嵌入式系统核心
  • 从Demo到生产:跨越AI Agent工程化的四道鸿沟
  • AI 生活应用 Python 环境:锁定依赖并一键自检
  • 用SVG-Edit在浏览器里做矢量设计:从零开始的完整上手攻略
  • e820_table 为空的情况
  • 2026年8月无锡外墙漏水维修防水公司推荐,高层高空渗水修缮避坑指南 - 聪居到家
  • PDF转文本与合并组合操作实测:内容提取与文档整合的效率评估
  • 0450-Bomb-生成地图道具
  • 数据结构与算法-动态规划、回溯与贪心
  • Codex 模型怎么选?GPT-5.6 Sol、Terra、Luna 等模型能力与应用场景对比
  • Java调用栈获取全解析:从Thread到StackWalker的四种方式对比与实践
  • Java编译参数-parameters详解:解决Spring MVC与MyBatis-Plus参数名缺失问题
  • IDEA 2022创建Maven Web项目:两种方式详解与Tomcat配置
  • IDEA自动导包与删包配置全解析:提升Java开发效率的核心技巧
  • Jupyter Notebook默认路径修改:原理、配置与高效工作流实践