洛谷 P3979 遥远的国度 做题记录

news/2025/3/14 17:05:10/文章来源:https://www.cnblogs.com/CodingGoat/p/18772442

前置芝士:树链剖分

思路

我们先随手画出一张图:

我们首先以 \(1\) 为根构造这颗树。
这张图比较特殊,因为这张图的编号同时也是他的 dfn 序。

我们将其分类讨论。
image
设当前根节点为 \(rt\),查询的节点为 \(x\),那么:

  • \(rt=x\) 时(图中蓝圈部分),我们可以访问所有的节点,那么就相当于是求全局最小值。
  • \(x\) 不在 \(1\)\(rt\) 的路径上时(图中橙圈部分),不同的根并未对这些造成影响。
  • \(x\)\(1\)\(rt\) 的路径上时(图中绿圈部分),他覆盖不到 \(x\)\(rt\) 路径上的最接近的儿子为根的树。

那么剩下就很好做了。

时间复杂度:\(O(n \log^2 n)\)

点击查看代码
#include<bits/stdc++.h>#define ll long long
#define i128 __int128#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define fst first 
#define scd second 
#define dbg puts("IAKIOI")using namespace std;int read() {int x=0,f=1; char c=getchar();for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }#define maxn 100050struct SegT {struct node {int mn,tag;}tr[maxn<<2];void psu(int idx) {tr[idx].mn=min(tr[lc(idx)].mn,tr[rc(idx)].mn);}void psd(int idx) {if(tr[idx].tag==-1) return ;tr[lc(idx)].mn=tr[rc(idx)].mn=tr[idx].tag;tr[lc(idx)].tag=tr[rc(idx)].tag=tr[idx].tag;tr[idx].tag=-1;}void build(int idx,int l,int r,int a[]) {tr[idx].tag=-1;if(l==r) {tr[idx].mn=a[l];return ;}int mid=(l+r)>>1;build(lc(idx),l,mid,a);build(rc(idx),mid+1,r,a);psu(idx);}void upd(int idx,int l,int r,int L,int R,int val) {if(L<=l&&r<=R) {tr[idx].mn=tr[idx].tag=val;return ;}psd(idx);int mid=(l+r)>>1;if(L<=mid) upd(lc(idx),l,mid,L,R,val);if(R>mid) upd(rc(idx),mid+1,r,L,R,val);psu(idx);}int query(int idx,int l,int r,int L,int R) {if(L<=l&&r<=R) return tr[idx].mn;psd(idx);int mid=(l+r)>>1,res=2141483647;if(L<=mid) res=query(lc(idx),l,mid,L,R);if(R>mid) res=min(res,query(rc(idx),mid+1,r,L,R));return res;}
}Tr;int n,m,w[maxn];
vector<int> G[maxn];struct TreDec {int siz,mxs,fa,dep;int dfn,top;
}tr[maxn];void dfs1(int u,int fa) {tr[u].dep=tr[fa].dep+1;tr[u].siz=1;tr[u].fa=fa;for(auto v:G[u]) if(v!=fa) {dfs1(v,u);tr[u].siz+=tr[v].siz;if(tr[tr[u].mxs].siz<tr[v].siz) tr[u].mxs=v;}
}int dfncnt,dfnval[maxn];
void dfs2(int u,int Ltop) {tr[u].top=Ltop;tr[u].dfn=++dfncnt;dfnval[dfncnt]=w[u];if(tr[u].mxs!=0) dfs2(tr[u].mxs,Ltop);for(auto v:G[u]) if(v!=tr[u].fa&&v!=tr[u].mxs) dfs2(v,v);
}
int rt=1;void updL(int x,int y,int val) {while(tr[x].top!=tr[y].top) {if(tr[tr[x].top].dep<tr[tr[y].top].dep) swap(x,y);Tr.upd(1,1,n,tr[tr[x].top].dfn,tr[x].dfn,val);x=tr[tr[x].top].fa;}if(tr[x].dep>tr[y].dep) swap(x,y);Tr.upd(1,1,n,tr[x].dfn,tr[y].dfn,val);
}int fnd(int x) {if(x==rt) return -1;if(tr[x].dfn>=tr[rt].dfn||tr[x].dfn+tr[x].siz-1<tr[rt].dfn) return 0;int u=rt;while(tr[u].top!=tr[x].top) {if(tr[tr[u].top].fa==x) return tr[u].top;u=tr[tr[u].top].fa;}return tr[x].mxs;
}int query(int x) {int fin=fnd(x);if(fin==-1) return Tr.tr[1].mn;if(fin==0) return Tr.query(1,1,n,tr[x].dfn,tr[x].dfn+tr[x].siz-1);int ans=Tr.query(1,1,n,1,tr[fin].dfn-1);if(tr[fin].dfn+tr[fin].siz-1<n) ans=min(ans,Tr.query(1,1,n,tr[fin].dfn+tr[fin].siz,n));return ans;
}void work() {in2(n,m);For(i,1,n-1) {int u,v;in2(u,v);G[u].push_back(v);G[v].push_back(u);}For(i,1,n) in1(w[i]);in1(rt);dfs1(1,0);dfs2(1,1);Tr.build(1,1,n,dfnval);while(m--) {int opt=read(); if(opt==1) in1(rt);else if(opt==2) {int x,y,d;in3(x,y,d);updL(x,y,d);} else {int x=read();cout<<query(x)<<'\n';}}
}signed main() {
//	freopen("data.in","r",stdin);
//	freopen("myans.out","w",stdout);
//	ios::sync_with_stdio(false); 
//	cin.tie(0); cout.tie(0);double stt=clock();int _=1;
//	_=read();
//	cin>>_;For(i,1,_) {work();}cerr<<"\nTotal Time is:"<<(clock()-stt)*1.0/1000<<" second(s)."<<'\n';return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/898741.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

actuator-系统监控功能

系统监控功能actuator-系统监控功能 引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId> </dependency>application.yml server:port: 8080servlet:context-path: …

首页页面布局(1)

import { TaskItem } from ../view/TaskItemimport { TaskStatisties } from ../view/TaskStatisties@Entry@Componentstruct TaskList { @State message: string = Hello World build() { Stack({alignContent:Alignment.BottomEnd}){ Column() { // 第1个模…

算法备案承诺书指南,5分钟速览

算法备案承诺书是算法备案初审的重要文件,和《落实算法安全责任基本情况》是初审阶段难度最大的两份材料。今天我就结合过往经验总结下这份文件的要点,帮助大家快速理解。TIPS:不要照搬这份模板,仅供学习了解。也不要买模板!不同行业和不同服务形态、不同服务对象都有区别…

信创替代必看:禅道/ONES/Jira功能对比及迁移方案

信创项目管理工具:赋能企业数字化转型的利器 在这个数字化转型的浪潮中,项目管理工具成为了企业发展的关键。它们不仅帮助团队提高效率,还能推动创新,为企业带来更大的价值。今天,让我们一起探索这些工具的魅力,以及它们如何在信创领域大放异彩。 项目管理工具的重要性 项…

VK1650 SOP16LED显示驱动芯片,适用于小家电,电磁炉,微波炉等

产品品牌:永嘉微电/VINKA 产品型号:VK1650 封装形式:SOP16/DIP16 概述 VK1650是一种带键盘扫描电路接口的 LED 驱动控制专用芯片,内部集成有数据锁存器、LED 驱动、键盘扫描等电路。SEG脚 接LED阳极,GRID脚接LED阴极,可支持8SEGx4GRID的点阵 LED显示。最大支持7x4按键。本…

Exsi网络不通的解决方法

Exsi网络不通,无法ping通网关 在虚拟机内部查看网卡是up状态 解决方法 找到对应的物理网络把默认协商随意修改成指定的某个速度的协商为什么这样解决不知道原因

jasyptStringEncryptor-ENC

Jasypt 是一个用于加密和解密字符串的 Java 库,常用于保护配置文件中的敏感信息(如数据库密码、API 密钥等)。StringEncryptor 是 Jasypt 的核心接口,用于执行字符串的加密和解密操作。以下是 StringEncryptor 的详细使用指南:1. 添加依赖 在 pom.xml 中添加 Jasypt 依赖:…

k8s/rancher 导入和使用 p12 或 pem 等证书

问题情景 将业务从 swarm迁移至k8s的过程中,遇到了一点证书导出/导入/挂载的问题,已经解决。 容器的证书目录结构 保持原来证书目录结构不变,避免了研发的代码改动。 # tree ./ ./ ├── 123 │ └── apiclient_cert.p12 ├── 456apiclient_cert.p12 └── apiclien…

洛谷题单指南-图论之树-P5588 小猪佩奇爬树

原题链接:https://www.luogu.com.cn/problem/P5588 题意解读:树中每个节点有一种颜色,计算每种颜色所有节点能用一条路径穿过的路径数。 解题思路: 直接枚举所有路径显然不可取,需要分情况来讨论,用乘法原理来解决。 首先,要通过dfs预处理出一些信息:siz[i]:节点i子树…

双非一本,小公司打杂,跳槽进了大厂!

大家好,我是R哥。 好久没有分享面试辅导的成功案例了,图片打码、过程梳理、文章编写,着实难写啊,太费时间了。 今天和大家分享一个普通本科、不知名小公司程序员,成功逆袭互联网大厂的真实案例。 如果你觉得自己学历一般,背景普通,没有 “985/211” 学历加持,也没有中大…

No.65 Vue---Axios 网络请求、Axios 网络的请求封装、网络请求跨域解决方案

一、Axios 网络请求Axios 是一个基于 promise 的网络请求库。1.1 安装ctrl + c :停止服务。 安装:npm install -save axios 安装完启动原来的服务:npm run serve 1.2 引入局部引用:import axios from axios; //局部引用 全局引用: 1.3 get请求方式//get請求方式axios({met…