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

好题集 (4) - CF487E Tourists

题目传送门。

概括一下题意:给定一简单无向联通图和每个点的点权,支持两种操作:修改某个点的点权,询问两点间所有简单路径上的点权最小值。

看到无向连通图和路径操作,首先联想到一个最容易的做法:建出圆方树,其中方点点权定义为与它相邻的圆点的点权最小值;然后树剖套线段树维护圆点,一个圆点的点权被修改时暴力更新与它相邻的方点。

但是这样做有一个问题:可以构造数据使得某个点同时处于很多(\(O(n)\) 级别)个环中,此时暴力更新方点显然不可做。

考虑新的做法。我们把无向图变成了树,因此不妨从树的一些特殊性质来考虑。

联想到一个重要性质:任何非根结点有且仅有一个父结点

于是,在原思路基础上,我们重新定义一个方点的点权为它所有儿子结点(由圆方树定义,这些结点一定都是圆点)中,点权的最小值。这样就一个圆点的点权就仅能影响到一个方点,修改时一个圆点时也就只需暴力修改一个方点。

接下来考虑如何完成这个暴力修改。更具体地,如何扣除之前点权的贡献,然后加入新的点权的贡献。

最小值这一信息不可差分,因此我们考虑用笨一点的方式。对于每个方点,我们都将它所有儿子的点权维护到一个动态的可重集里;每次暴力修改时,都将原来的点权从集合中删除,插入新的点权,再取出集合中最小的数,将这个数赋给方点点权。这个可重集可以直接用 multiset 来实现。

最后还有一个 corner case:若查询时两端点的 LCA 是方点,那么我们的树剖会跳过 LCA 的父亲,我们要查的链上就少了一个点。此时需要特判一下,手动将 LCA 的父亲计入贡献。

于是就做到了 \(O(n)\) 预处理,\(O(\log^2n)\) 查询,\(O(\log n)\) 修改。这道 *3200 就被解决了。

代码:

#include<iostream>
#include<set>
#include<stack>
using namespace std;const int N=2e5+5;int n,m,q;int w[N]/*点权*/,nw[N]/*树剖后的新点权*/;namespace SGT{#define ls u<<1#define rs u<<1|1#define mid (L+R>>1)int mn[N<<2];inline void pushup(int u){return mn[u]=min(mn[ls],mn[rs]),void();}inline void build(int u,int L,int R){if(L==R)return mn[u]=nw[L],void();return build(ls,L,mid),build(rs,mid+1,R),pushup(u),void();}inline void upd(int u,int tar,int val,int L,int R){if(tar>R||tar<L)return ;if(L==R)return mn[u]=val,void();return ((tar<=mid)?(upd(ls,tar,val,L,mid)):(upd(rs,tar,val,mid+1,R))),pushup(u),void();}inline int qry(int u,int l,int r,int L,int R){if(l>r)swap(l,r);if(l>R||L>r)return 1e9;if(l<=L&&R<=r)return mn[u];return min(qry(ls,l,r,L,mid),qry(rs,l,r,mid+1,R));}inline int qry_(int u,int tar,int L,int R){if(tar>R||tar<L)return 0;if(L==R)return mn[u];return ((tar<=mid)?(qry_(ls,tar,L,mid)):(qry_(rs,tar,mid+1,R)));}#undef ls#undef rs#undef mid}using namespace SGT;namespace graph{namespace basic{#define rep1 for(int i=head1[u];~i;i=e1[i].nxt)#define rep2 for(int i=head2[u];~i;i=e2[i].nxt)#define handle1 int v=e1[i].v;#define handle2 int v=e2[i].v;int idx1=-1,idx2=-1;int head1[N],head2[N];struct edge{int v,nxt;}e1[N<<3],e2[N<<3];inline void add1(int u,int v){return e1[++idx1]={v,head1[u]},head1[u]=idx1,void();}inline void add2(int u,int v){return e2[++idx2]={v,head2[u]},head2[u]=idx2,void();}}using namespace basic;namespace YFS{int tim/*时间戳*/,id/*方点编号*/;int low[N],dfn[N];stack<int>s;inline void getmn(int &a,int b){return a=(a<b?a:b),void();}inline void Tarjan(int u){low[u]=dfn[u]=++tim,s.push(u);rep1{handle1;if(!dfn[v]){Tarjan(v);getmn(low[u],low[v]);if(low[v]^dfn[u])continue ;++id;while(s.top()^v)add2(id,s.top()),add2(s.top(),id),s.pop();add2(u,id),add2(id,u),add2(v,id),add2(id,v),s.pop();}else getmn(low[u],dfn[v]);}return ;}}using namespace YFS;namespace SP_{int fa[N],dep[N],sz[N],son[N];inline void dfs(int u,int f){fa[u]=f,sz[u]=1,dep[u]=dep[f]+1;rep2{handle2;if(v==f)continue ;dfs(v,u);sz[u]+=sz[v];if(sz[son[u]]<sz[v])son[u]=v;}return ;}int ntim/*时间戳*/;int top[N],ndfn[N]/*适用于树剖的 dfs 序*/;inline void df5(int u,int t){top[u]=t,ndfn[u]=++ntim,nw[ntim]=w[u];if(!son[u])return ;df5(son[u],t);rep2{handle2;if(v==fa[u]||v==son[u])continue ;df5(v,v);}return ;}inline int LCA(int u,int v){while(top[u]^top[v]){if(dep[top[u]]<dep[top[v]])swap(u,v);u=fa[top[u]];}return dep[u]<dep[v]?u:v;}multiset<int>val[N]/*方点的权值集合*/;inline void init(int u){w[u]=1e9;rep2{handle2;if(v>n||v==fa[u])continue ;getmn(w[u],w[v]),val[u].insert(w[v]);}return ;}inline void upd_dot(int u,int val){return upd(1,ndfn[u],val,1,id),void();}inline int qry_path(int u,int v){int res=1e9;while(top[u]^top[v]){if(dep[top[u]]<dep[top[v]])swap(u,v);getmn(res,qry(1,ndfn[u],ndfn[top[u]],1,id));u=fa[top[u]];}return getmn(res,qry(1,ndfn[u],ndfn[v],1,id)),res;}inline int qry_dot(int u){return qry_(1,ndfn[u],1,id);}}using namespace SP_;#undef rep1#undef rep2#undef handle1#undef handle2}using namespace graph;inline void work(){char op;cin>>op;if(1==2){puts("wow");}else if(op=='C'){int a,v;cin>>a>>v;int f=fa[a];if(f){val[f].erase(val[f].find(qry_dot(a)));val[f].insert(v);upd_dot(f,*val[f].begin());}upd_dot(a,v);}else if(op=='A'){int a,b;cin>>a>>b;int lca=LCA(a,b);int res=1e9;if(lca>n)getmn(res,qry_dot(fa[lca]));getmn(res,qry_path(a,b)),cout<<res<<"\n";}return ;
}signed main(){for(int i=0;i<N;++i)head1[i]=head2[i]=-1;ios::sync_with_stdio(false);cin.tie(0);cin>>n>>m>>q;id=n;for(int i=1;i<=n;++i)cin>>w[i];for(int i=1;i<=m;++i){int u,v;cin>>u>>v;add1(u,v),add1(v,u);}Tarjan(1),dfs(1,0);for(int u=n+1;u<=id;++u)init(u);df5(1,1),build(1,1,id);while(q--)work();return 0;
}

提交记录。

http://www.jsqmd.com/news/40508/

相关文章:

  • 完整教程:OpenHarmony内核基础:LiteOS-M内核与POSIX/CMSIS接口
  • Http基础协议和解析 - 指南
  • 2025年问题肌培训企业最新专业推测top5:技术创新与实战效能全面升级,做好皮肤管理,搞定皮肤亚健康、祛痘祛斑。
  • 备份一点有趣的东西(期刊资源)
  • 11.14模拟赛
  • Swift 和 Tesseract OCR 进行验证码识别
  • 实用指南:云计算生态及学习方向和就业领域方向
  • 2025年成绩差的孩子该用学习机吗?松鼠AI双线模式测评及选购指南
  • 2025年11月徐州网站开发服务商怎么选
  • 2025年11月徐州网站建设服务商综合评测与选择指南
  • 2025年11月徐州AI GEO平台综合评测与权威推荐
  • 2025年国内徐州宣传片公司品牌权威推荐榜单
  • 好题集 (3) - LG P2122 还教室
  • 好题集 (2) - LG P4550 收集邮票
  • python3如何切换路径
  • 腾讯元宝如何导出内容为文档
  • 2025-11-14 早报新闻
  • Number Theory
  • 2025年11月眉笔选购指南:花西子/植村秀/珂拉琪等5大品牌实测,新手闭眼入款竟是它​
  • Upcoming Rust language features for kernel development - 教程
  • 详细介绍:Linux网络性能测试利器:iperf3使用指南
  • linux 安装telnet 服务
  • 实用指南:【STM32】RTC实时时钟
  • 探索乐泰胶水:性能与适用场景全解析
  • 【System Beats!】第七章 链接
  • oracle 11g r2 linux
  • 实用指南:接口测试 | 使用Postman实际场景化测试
  • 应用程序建立的数据库连接,也就是非交互式连接 是什么时候开始的?什么时候结束?连接结束后 会影响应用程序操作db失败吗? 还有就是如果连接关闭了 会立马重新建立新的连接吗?
  • 2025高压合金管实力厂家推荐榜:5310/6479 高压合金管型号领衔,天津大无缝联合钢铁有限公司五星领跑工业用材赛道
  • Kafka协调器:消费者组管理与重平衡机制 - 指南