You are given an unrooted weighted tree \(T\) with vertices \(1,2,…,n\). Please answer some queries.

We define \(dist(i,j)\) as the distance between vertex i and vertex \(j\) in \(T\).

For each query, you are given two integers \(l,r\). Please answer the value of

\[\min\limits_{l\le i<j\le r}dis(i,j)
\]

Input

The first line contains one integer \(n (1≤n≤2×10^5)\), the number of vertices in the tree.

Each of the next n−1 lines describes an edge of the tree. Edge i is denoted by three integers \(a_i,b_i,w_i (1≤a_i,b_i≤n,1≤w_i≤10^9)\), the labels of vertices it connects and its weight.

Then one line contains one integer \(q (1≤q≤10^6)\), the number of queries.

Each of the following q lines contains two integers \(l,r\) \((1≤l≤r≤n)\) describing a query.

It is guaranteed that the given edges form a tree.

Output

For each query, output the answer in one line. If there is no \(i,j\) such that \(1≤i<j≤r\), the answer is \(−1\).

距离问题,考虑点分治

对于一个目前的根 \(x\) 以及若干个连通块中的点,可以把所有点按照编号排序。此时考虑把一些点对设为可能成为答案的点对。

如果此时有 \(i,j,k\) 满足 \(i<j<k\) 且 \(dep_i\ge dep_j,dep_k\),那么 \((i,k)\) 一定不是可以满足要求的点对。因为如果区间包含了 \((i,k)\),一定包含了 \((j,k)\),同时 \(dep_i+dep_j>dep_j+dep_k\)。所以我们不用理他。

由此,我们可以点分治完,对于每个连通块里的点 \(i\),按照编号排序,然后用单调栈找到左右最靠近他的 \(dep\) 小于等于 他的第一个数 \(lst_i,nxt_i\)。容易发现最后得到可能为答案的点对最多只有 \(O(nlogn)\) 个。

把点对按照大的那个数排序,然后扫描线,需要支持单点改,求后缀最小值。树状数组维护即可。对于一个点对 \((l,r,dist(l,r))\),可以当扫到 \(r\) 时把 \(l\) 与 \(dist(l,r)\) 去最小值。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e5+5;
const LL INF=1e18;
int n,v[N],hd[N],m,rt,k,q,f[N<<3],sz[N],mx,e_num,nwp,st[N],tp,nxt[N],lst[N];
LL tr[N],ans[N<<3];
struct edge{
int v,nxt,w;
}e[N<<1];
struct node{
int l,r;
LL dep;
bool operator<(const node&n)const{
return r<n.r;
}
}p[N<<6];
struct dian{
int x;
LL dep;
bool operator<(const dian&d)const{
return x<d.x;
}
}a[N];
vector<int>g[N];
void add_edge(int u,int v,int w)
{
e[++e_num]=(edge){v,hd[u],w};
hd[u]=e_num;
}
void sou(int x,LL dep,int f)
{
a[++m]=(dian){x,dep};
for(int j=hd[x];j;j=e[j].nxt)
if(!v[e[j].v]&&e[j].v^f)
sou(e[j].v,dep+e[j].w,x);
}
void suo(int x,int f,int n)
{
int cnt=0;
sz[x]=1;
for(int i=hd[x];i;i=e[i].nxt)
{
if(!v[e[i].v]&&e[i].v^f)
{
suo(e[i].v,x,n);
sz[x]+=sz[e[i].v];
cnt=max(cnt,sz[e[i].v]);
}
}
cnt=max(cnt,n-sz[x]);
if(cnt<mx)
mx=cnt,rt=x;
}
int findrt(int x,int n)
{
rt=0,mx=2000000000;
suo(x,0,n);
// printf("%d\n",mx);
return rt;
}
void tosz(int x,int f)
{
sz[x]=1;
for(int i=hd[x];i;i=e[i].nxt)
{
if(!v[e[i].v]&&e[i].v^f)
{
tosz(e[i].v,x);
sz[x]+=sz[e[i].v];
}
}
}
void dfs(int x)
{
// printf("hjhyyds:%d\n",x);
sou(x,m=0,0);
tosz(rt,0);
sort(a+1,a+m+1);
// for(int i=1;i<=m;i++)
// printf("%d %d\n",a[i].x,a[i].dep);
tp=0;
// if(x==5)
// puts("chtyyds:");
for(int i=1;i<=m;i++)
{
while(tp&&a[st[tp]].dep>=a[i].dep)
nxt[st[tp--]]=i;
st[++tp]=i;
// if(x==5)
// {
// for(int j=1;j<=tp;j++)
// printf("%d ",st[j]);
// puts("");
// }
}
// puts("qzmyyds");
tp=0;
for(int i=m;i>=1;i--)
{
while(tp&&a[st[tp]].dep>=a[i].dep)
lst[st[tp--]]=i;
st[++tp]=i;
}
for(int i=1;i<=m;i++)
{
if(lst[i])
p[++k]=(node){a[lst[i]].x,a[i].x,a[lst[i]].dep+a[i].dep} ;
if(nxt[i])
p[++k]=(node){a[i].x,a[nxt[i]].x,a[nxt[i]].dep+a[i].dep};
lst[i]=nxt[i]=0;
}
// if(x==5)
// {
// for(int i=1;i<=m;++i)
// printf("%d %d\n",a[i].x,a[i].dep);
// printf("xzd%%%:%d\n",nxt[1]);
// }
v[x]=1;
for(int i=hd[x];i;i=e[i].nxt)
if(!v[e[i].v])
dfs(findrt(e[i].v,sz[e[i].v]));
}
void update(int x,LL y)
{
// printf("%d %lld\n",x,y) ;
for(;x<=n;x+=x&-x)
tr[x]=min(tr[x],y);
}
LL query(int x)
{
// printf("qu:%d\n",x);
LL ret=1e18;
for(;x;x-=x&-x)
ret=min(ret,tr[x]);
// printf("%lld\n",ret);
return ret;
}
signed main()
{
memset(tr,0x7f,sizeof(tr));
scanf("%d",&n);
for(int i=1,u,v,w;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);
add_edge(v,u,w);
}
scanf("%d",&q);
for(int i=1,y;i<=q;i++)
{
scanf("%d%d",f+i,&y);
g[y].push_back(i);
}
dfs(findrt(1,n));
sort(p+1,p+k+1);
// for(int i=1;i<=k;i++)
// printf("%d %d %lld\n",p[i].l,p[i].r,p[i].dep);
nwp=0;
for(int i=1;i<=n;i++)
{
while(nwp^k&&p[nwp+1].r==i)
{
++nwp;
update(n-p[nwp].l+1,p[nwp].dep);
}
for(int j=0;j<g[i].size();j++)
ans[g[i][j]]=query(n-f[g[i][j]]+1);
}
for(int i=1;i<=q;i++)
printf(ans[i]==INF? "-1\n":"%lld\n",ans[i]);
}

[gym104076][CCPC2022济南站L] Tree Distance的更多相关文章

  1. 2020ICPC济南站 J.Tree Constructer

    题目大意:给定一棵N个顶点的树,顶点为1~N,对于一个序列A1,A2,-,An,若Ai | Aj == 2^60-1,则会连一条边(i,j).要求求出一个序列,可以唯一确定所给定的树. 思路:考虑到树 ...

  2. Distance on the tree

    Distance on the tree https://nanti.jisuanke.com/t/38229 DSM(Data Structure Master) once learned abou ...

  3. 2019南昌邀请赛网络预选赛 J.Distance on the tree(树链剖分)

    传送门 题意: 给出一棵树,每条边都有权值: 给出 m 次询问,每次询问有三个参数 u,v,w ,求节点 u 与节点 v 之间权值 ≤ w 的路径个数: 题解: 昨天再打比赛的时候,中途,凯少和我说, ...

  4. 南昌网络赛 Distance on the tree 主席树+树剖 (给一颗树,m次查询ui->vi这条链中边权小于等于ki的边数。)

    https://nanti.jisuanke.com/t/38229 题目: 给一颗树,m次查询ui->vi这条链中边权小于等于ki的边数. #include <bits/stdc++.h ...

  5. 2019年ICPC南昌网络赛 J. Distance on the tree 树链剖分+主席树

    边权转点权,每次遍历到下一个点,把走个这条边的权值加入主席树中即可. #include<iostream> #include<algorithm> #include<st ...

  6. POJ 6621: K-th Closest Distance(主席树 + 二分)

    K-th Closest Distance Time Limit: 20000/15000 MS (Java/Others)    Memory Limit: 524288/524288 K (Jav ...

  7. 2019杭电多校第四场hdu6621 K-th Closest Distance(二分答案+主席树)

    K-th Closest Distance 题目传送门 解题思路 二分答案+主席树 先建主席树,然后二分答案mid,在l和r的区间内查询[p-mid, p+mid]的范围内的数的个数,如果大于k则说明 ...

  8. AOJ DSL_2_C Range Search (kD Tree)

    Range Search (kD Tree) The range search problem consists of a set of attributed records S to determi ...

  9. 【BZOJ-4353】Play with tree 树链剖分

    4353: Play with tree Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 31  Solved: 19[Submit][Status][ ...

  10. 【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2459  Solved: 834[Submit][Status][Discu ...

随机推荐

  1. 前后端分离中台框架 Admin.Core 学习-介绍与配置说明

    中台框架后端项目 Admin.Core 的介绍与配置说明 中台admin是前后端分离权限管理系统,Admin.Core为后端项目,基于.NET 7.0开发. 支持多租户.数据权限.动态 Api.任务调 ...

  2. 深入理解Linux内核——内存管理(1)

    提要:本系列文章主要参考MIT 6.828课程以及两本书籍<深入理解Linux内核> <深入Linux内核架构>对Linux内核内容进行总结. 内存管理的实现覆盖了多个领域: ...

  3. H.265+SRS6.0服务器部署

    H.265+SRS6.0服务器部署 SRS从6.0开始,全面支持H.265,包括RTMP.FLV.HLS.GB28181.WebRTC等等.具体的服务器部署及H.265推流步骤如下. 1. SRS 要 ...

  4. 接口自动化测试项目 | IHRM登录接口自动化测试

    项目内容如下: ### 需求- 地址:http://ihrm-java.itheima.net/#/login- 测试接口: - 登录接口:针对登录的13个cases### 技术 - V1:pytho ...

  5. shell、python时间函数小结

    有时需要写一些定时任务脚本,简单总结一下,备忘. 1. 获取当前时间 python 在windows下精确到0.001秒,linux下时间精度为0.000001秒 >>> impor ...

  6. 开源.NetCore通用工具库Xmtool使用连载 - 图形验证码篇

    [Github源码] <上一篇> 介绍了Xmtool工具库中的Web操作类库,今天我们继续为大家介绍其中的图形验证码类库. 图形验证码是为了抵御恶意攻击出现的一种设计:例如用户登录.修改密 ...

  7. Github工具库

    0x01 漏洞练习平台 WebGoat漏洞练习平台: https://github.com/WebGoat/WebGoat webgoat-legacy漏洞练习平台: https://github.c ...

  8. 文心一言 VS 讯飞星火 VS chatgpt (95)-- 算法导论9.2 4题

    四.用go语言,假设用RANDOMIZED-SELECT 去选择数组 A=(3,2,9,0,7,5,4,8,6,1)的最小元素,给出能够导致 RANDOMIZED-SELECT最坏情况发生的一个划分序 ...

  9. Llama2-Chinese项目:4-量化模型

    一.量化模型调用方式   下面是一个调用FlagAlpha/Llama2-Chinese-13b-Chat[1]的4bit压缩版本FlagAlpha/Llama2-Chinese-13b-Chat-4 ...

  10. 使用 Docker Compose 部署 RabbitMQ 的一些经验与踩坑记录

    前言 RabbitMQ 是一个功能强大的开源消息队列系统,它实现了高效的消息通信和异步处理. 本文主要介绍其基于 Docker-Compose 的部署安装和一些使用的经验. 特点 成熟,稳定 消息持久 ...