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

LGP11364 [NOIP 2024] 树上查询 学习笔记

LGP11364 [NOIP 2024] 树上查询 学习笔记

Luogu Link

前言

过了八个月后……

\(\text{Finally, done.}\)

题意简述

给定一棵 \(n\) 个结点、以 \(1\) 为根的树。定义一个结点 \(u\) 的深度为 \(1\to u\) 简单路径上的结点数量。

定义 \(\text{LCA*}(l,r)\) 为编号在 \([l,r]\) 中的所有结点的最近公共祖先。

\(m\) 个询问,每个询问给出 \(l,r,k\),你需要回答:\(\max_{l\le l'\le r'\le r\land r'-l'+1\ge k}dep_{\text{LCA*}(l',r')}\)

\(n,m\le 5\times 10^5\)。对于每个询问保证 \(r'-l'+1\ge k\)。虽然两 \(\log\) 有不小机会干过去,但那设计上只有 \(\text{80pts}\)。为了达到训练效果,请写单 \(\log\) 做法。

做法解析

首先这个问题需要一个转化。

问题转化完毕。有 \(O(n)\) 个形如 \([sl,sr]\),权值为 \(v\) 的线段,\(m\) 次询问,每次给定 \([ql,qr,k]\),问与区间 \([ql,qr]\) 交集至少为 \(k\) 的线段中最大的权值。

首先显然可以三维偏序来做,此不赘述。现在你有 \(\text{80pts}\) 了。但是我们来思考优美的单 \(\log\)

想要单 \(\log\) 需要偏序关系降到二维。怎么降呢?答案是分类讨论。
对于 \(sl\le ql\le qr\le sr\) 的,我们不需要考虑 \(k\) 这一维的偏序,因为题目保证了 \(qr-ql+1\ge k\),所以也必然有 \(sr-sl+1\ge k\)。这里就是直接二维偏序就行。

对于 \(ql\le sl\le qr\le sr\)\(sl\le ql\le sr\le qr\) 的,我们去扫描 \(k\) 这一维,这个想法较为重要,值得学习:

  • 一方面我们发现这两个问题有对称性,而 \(k\) 是它们都免不掉要扫的一维。
  • 另一方面因为我们需要降维,我们必须就要松掉一维度的限制。我们对于 \(ql\le sl\le qr\le sr\) 松掉 \(qr\le sr\) 这一维,对于 \(sl\le ql\le sr\le qr\) 松掉 \(sl\le ql\) 这一维。这样我们既降了维,又允许出现 \(ql\le sl\le sr\le qr\) 的情况,顺便就把它统计上了。

这时如果你饭堂了,可能会问出这样一个问题:

\(ql\le sl\le sr\le qr\) 的情况不是明晃晃算重了吗?

的确,这种情况被考虑了两遍,但我们在做的是更新最大值而并不是加和,所以最大值你重复扫对答案正确性没有影响。

推而广之来讲,求最大值的时候,你更新失败是在 maxxer(ans,0),就对答案正确性没有影响。

代码实现

纯板,代码没有任何好讲的。

#include <bits/stdc++.h>
using namespace std;
using namespace obasic;
const int MaxN=5e5+5;
int N,M,X,Y,Z,ans[MaxN];
vector<int> Tr[MaxN];
void addudge(int u,int v){Tr[u].push_back(v);Tr[v].push_back(u);
}
int tfa[MaxN],dep[MaxN],siz[MaxN],hvs[MaxN];
void dfs1(int u,int f){dep[u]=dep[f]+1,tfa[u]=f,siz[u]=1;for(int v : Tr[u]){if(v==f)continue;dfs1(v,u),siz[u]+=siz[v];if(siz[v]>siz[hvs[u]])hvs[u]=v;}
}
int dfn[MaxN],dcnt,top[MaxN];
void dfs2(int u,int t){dfn[u]=++dcnt,top[u]=t;if(hvs[u])dfs2(hvs[u],t);for(int v : Tr[u])if(v!=tfa[u]&&v!=hvs[u])dfs2(v,v);
}
int getlca(int x,int y){while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]])swap(x,y);x=tfa[top[x]];}return dep[x]<=dep[y]?x:y;
}
struct SegTree{int mx[MaxN<<2];int ls(int u){return u<<1;}int rs(int u){return (u<<1)|1;}void pushup(int u){mx[u]=max(mx[ls(u)],mx[rs(u)]);}void update(int u,int cl,int cr,int dd,int x){if(cl==cr){maxxer(mx[u],x);return;}int cmid=(cl+cr)>>1;dd<=cmid?update(ls(u),cl,cmid,dd,x):update(rs(u),cmid+1,cr,dd,x);pushup(u);}int getmax(int u,int cl,int cr,int dl,int dr){if(dl<=cl&&cr<=dr)return mx[u];int cmid=(cl+cr)>>1,res=0;if(dl<=cmid)maxxer(res,getmax(ls(u),cl,cmid,dl,dr));if(dr>cmid)maxxer(res,getmax(rs(u),cmid+1,cr,dl,dr));return res;}
}SgT[3];
int A[MaxN],H[MaxN],stk[MaxN],ktp;
int sls[MaxN],srs[MaxN];
struct anob{int l,r,x;}S[MaxN];
vector<pii> G2[MaxN],Q2[MaxN];
vector<anob> G1[MaxN],Q1[MaxN];
void dfs3(int u,int l,int r){S[u]={l,r,H[u]};if(sls[u])dfs3(sls[u],l,u);if(srs[u])dfs3(srs[u],u+1,r);
}
int main(){readi(N);for(int i=1;i<N;i++)readis(X,Y),addudge(X,Y);dfs1(1,0),dfs2(1,1);for(int i=1;i<N;i++)A[i]=getlca(i,i+1),H[i]=dep[A[i]];for(int i=1,k;i<N;i++,ktp=k){for(k=ktp;H[stk[k]]>H[i];k--);if(k<ktp)sls[i]=stk[k+1];srs[stk[k]]=i,stk[++k]=i;}dfs3(stk[1],1,N);readi(M);for(int i=1;i<=M;i++){readis(X,Y,Z);Q1[Z].push_back({X,Y,i});Q2[X].push_back({Y,i});}for(int i=1;i<N;i++){auto [l,r,h]=S[i];G1[r-l+1].push_back(S[i]);}for(int i=1;i<=N;i++)G1[1].push_back({i,i,dep[i]});for(int k=N;k>=1;k--){for(auto [l,r,h] : G1[k]){SgT[0].update(1,1,N,l,h);SgT[1].update(1,1,N,r,h);}for(auto [l,r,id] : Q1[k]){maxxer(ans[id],SgT[0].getmax(1,1,N,l,r-k+1));maxxer(ans[id],SgT[1].getmax(1,1,N,l+k-1,r));}}for(int i=1;i<N;i++){auto [l,r,h]=S[i];G2[l].push_back({r,h});}for(int i=1;i<=N;i++){for(auto [r,h] : G2[i])SgT[2].update(1,1,N,r,h);for(auto [r,id] : Q2[i])maxxer(ans[id],SgT[2].getmax(1,1,N,r,N));}for(int i=1;i<=M;i++)writil(ans[i]);return 0;
}
http://www.sczhlp.com/news/8220/

相关文章:

  • 严格WQS二分
  • 2025 暑期 mx 集训 7.21
  • 8月8号
  • GPT-5 API 请求参数调整,避坑指南(汇总)
  • 题解:CF2048F Kevin and Math Class
  • gem5流程学习-1
  • SPI详细讲解+W25Q128验证
  • 【自学嵌入式:stm32单片机】蜂鸣器
  • 带 PVC 的 Pod 提交后时序事件
  • C#自学笔记:匿名函数与Lambda表达式
  • 如何高效率使用 Cursor ?
  • 注意力头
  • 8月8日
  • 一键上云不是梦!Apache Dubbo 发布微服务集群部署与全新控制台
  • 安装libretranslate
  • 解决 Vue 路由在 IIS 中的 404 问题
  • 位置嵌入
  • threejs之灯光不跟随OrbitControls控制器旋转
  • MAC在Docker上部署Ollama详细教程
  • 8月8日随笔
  • 场景题——高并发
  • 权重衰减系数
  • Burp Suite 拦截和修改 HTTP 接口请求
  • Jvm记录GC日志输出
  • 学习率衰减的 epoch 数
  • AD方案(OpenLDAP或微软AD)适配信创存在的不足以及可能优化方案 - 指南
  • 在Java中拆平(扁平化)List主要有以下几种常见方法:
  • 漫花国货居家
  • 【pwn做题记录】ciscn_2019_ne_5 1
  • JL一拖八燒錄器帶電池升級