「2017 山东三轮集训 Day7」Easy

练习一下动态点分

每个点开一个线段树维护子树到它的距离

然后随便查询一下就可以了

注意线段树开大点...


Code:

#include <cstdio>
#include <cctype>
#include <algorithm>
using std::min;
template <class T>
void read(T &x)
{
x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
const int N=1e5+10;
const int inf=0x3f3f3f3f;
int head[N],to[N<<1],Next[N<<1],edge[N<<1],cnt;
void add(int u,int v,int w)
{
to[++cnt]=v,edge[cnt]=w,Next[cnt]=head[u],head[u]=cnt;
}
namespace RMQLCA
{
int st[19][N<<1],Log[N<<1],dfn[N],dep[N],dis[N],clock;
void dfs(int now,int fa)
{
dep[now]=dep[fa]+1;
st[0][++clock]=now;
dfn[now]=clock;
for(int v,i=head[now];i;i=Next[i])
if((v=to[i])!=fa)
dis[v]=dis[now]+edge[i],dfs(v,now),st[0][++clock]=now;
}
void init()
{
dfs(1,0);
for(int i=2;i<=clock;i++) Log[i]=Log[i>>1]+1;
for(int j=1;j<=18;j++)
for(int i=1;i<=clock-(1<<j)+1;i++)
{
int x=st[j-1][i],y=st[j-1][i+(1<<j-1)];
st[j][i]=dep[x]<dep[y]?x:y;
}
}
int LCA(int x,int y)
{
x=dfn[x],y=dfn[y];
if(x>y) std::swap(x,y);
int d=Log[y+1-x];
x=st[d][x],y=st[d][y-(1<<d)+1];
return dep[x]<dep[y]?x:y;
}
int getdis(int x,int y)
{
return dis[x]+dis[y]-(dis[LCA(x,y)]<<1);
}
}
namespace seg
{
#define ls ch[now][0]
#define rs ch[now][1]
int ch[N*100][2],mi[N*100],tot;
void ins(int &now,int l,int r,int p,int d)
{
if(!now) now=++tot;
if(l==r) {mi[now]=d;return;}
int mid=l+r>>1;
if(p<=mid) ins(ls,l,mid,p,d);
else ins(rs,mid+1,r,p,d);
mi[now]=min(mi[ls],mi[rs]);
}
int query(int now,int L,int R,int l,int r)
{
if(!now) return inf;
if(L==l&&R==r) return mi[now];
int Mid=L+R>>1;
if(r<=Mid) return query(ls,L,Mid,l,r);
else if(l>Mid) return query(rs,Mid+1,R,l,r);
else return min(query(ls,L,Mid,l,Mid),query(rs,Mid+1,R,Mid+1,r));
}
void init()
{
mi[0]=inf;
}
}
using RMQLCA::getdis;
using seg::query;
using seg::ins;
int siz[N],del[N],par[N],root[N],si,mi,rt,n,m;
void dfsrt(int now,int fa)
{
siz[now]=1;
int mx=0;
for(int v,i=head[now];i;i=Next[i])
if((v=to[i])!=fa&&!del[v])
{
dfsrt(v,now);
siz[now]+=siz[v];
mx=mx>siz[v]?mx:siz[v];
}
mx=mx>si-siz[now]?mx:si-siz[now];
if(mx<mi) mi=mx,rt=now;
}
void dfs(int now,int rt,int fa,int dis)
{
ins(root[rt],1,n,now,dis);
siz[now]=1;
for(int v,i=head[now];i;i=Next[i])
if((v=to[i])!=fa&&!del[v])
dfs(v,rt,now,dis+edge[i]),siz[now]+=siz[v];
}
void divide(int now)
{
del[now]=1;
dfs(now,now,0,0);
for(int v,i=head[now];i;i=Next[i])
if(!del[v=to[i]])
{
si=siz[v],mi=n;
dfsrt(v,0);
par[rt]=now;
divide(rt);
}
}
int main()
{
read(n);
for(int u,v,d,i=1;i<n;i++) read(u),read(v),read(d),add(u,v,d),add(v,u,d);
RMQLCA::init();
seg::init();
si=n,mi=n,dfsrt(1,0),divide(rt);
read(m);
for(int l,r,x,s,ans,i=1;i<=m;i++)
{
read(l),read(r),read(x),s=x;
ans=inf;
while(x)
{
int mi=query(root[x],1,n,l,r);
ans=min(ans,mi+getdis(s,x));
x=par[x];
}
printf("%d\n",ans);
}
return 0;
}

2019.3.17

「2017 山东三轮集训 Day7 解题报告的更多相关文章

  1. 【loj6145】「2017 山东三轮集训 Day7」Easy 动态点分治+线段树

    题目描述 给你一棵 $n$ 个点的树,边有边权.$m$ 次询问,每次给出 $l$ .$r$ .$x$ ,求 $\text{Min}_{i=l}^r\text{dis}(i,x)$ . $n,m\le ...

  2. 「2017 山东三轮集训 Day7」Easy

    一棵带边权的树,多次询问 $x$ 到编号为 $[l,r]$ 的点最短距离是多少 $n \leq 100000$ sol: 动态点分治,每层重心维护到所有点的距离 查询的时候在管辖这个点的 log 层线 ...

  3. #6145. 「2017 山东三轮集训 Day7」Easy 动态点分治

    \(\color{#0066ff}{题目描述}\) JOHNKRAM 最近在参加 C_SUNSHINE 举办的聚会. C 国一共有 n 座城市,这些城市由 n−1 条无向道路连接.任意两座城市之间有且 ...

  4. LOJ #6145. 「2017 山东三轮集训 Day7」Easy 点分树+线段树

    这个就比较简单了~ Code: #include <cstdio> #include <algorithm> #define N 100004 #define inf 1000 ...

  5. 「2017 山东三轮集训 Day1」Flair

    模拟赛的题 好神仙啊 题面在这里 之前的Solution很蠢 现在已经update.... 题意 有$ n$个商品价格均为$ 1$,您有$ m$种面值的货币,面值为$ C_1..C_m$ 每种物品你有 ...

  6. 【loj6142】「2017 山东三轮集训 Day6」A 结论题+Lucas定理

    题解: 当奇数 发现答案就是C(n,1)^2+C(n,3)^2+...C(n,n)^2 倒序相加,发现就是C(2n,n) 所以答案就是C(2n,n)/2 当偶数 好像并不会证 打表出来可以得到 2.当 ...

  7. [LOJ6145][2017 山东三轮集训 Day7]Easy

    loj description 一棵树,每次给出\(l,r,x\),求从点\(x\)出发到达\([l,r]\)中任意一点的最短距离. sol 动态点分治. 建出点分树后,在每个节点上用以点编号为下标的 ...

  8. loj #6138. 「2017 山东三轮集训 Day4」Right

    题目: 题解: 暴力一波 \(SG\) 函数可以发现这么一个规律: \(p\) 为奇数的时候 : \(SG(n) = n \% 2\) \(p\) 为偶数的时候 : \(SG(n) = n \% (p ...

  9. loj #6136. 「2017 山东三轮集训 Day4」Left

    题目: 题解: 我们可以发现所有的交换器都是一个位置连接着下一层左侧的排序网络,另一个位置连着另一侧的排序网络. 而下一层是由两个更低阶的排序网络构成的. 两个网络互不干扰.所以我们可以通过第一行和最 ...

随机推荐

  1. 使用junit测试

    package creeper; import java.util.Scanner; public class size { private static int intercePosition = ...

  2. final域的内存语义

    final 一.final的基本语义 final关键字可以用来修饰类.方法和变量(包括成员变量和局部变量) 当用final修饰一个类时,表明这个类不能被继承. 当用final修饰一个方法时,表明这个方 ...

  3. springIOC源码分析(BeanFactroy)

    启动spring容器加载bean的方式有两种:最基本的容器BeanFactory和高级容器ApplicationContext.这篇文章介绍使用BeanFactory加载bean时的整个过程,当然,A ...

  4. js关闭当前页

    /*关闭当前页*/ function closeCurrentPage() { var userAgent = navigator.userAgent; if (userAgent.indexOf(& ...

  5. python学习笔记(8)--random库的使用

    伪随机数:采用梅森旋转算法生成的伪随机序列中元素 使用random库 一.基本随机函数 随机数需要一个种子,依据这个种子通过梅森旋转算法产生固定序列的随机数.seed(a=None)  初始化给定的随 ...

  6. centso7 安装redmine

    一.安装rvm ###安装rvm gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D3 ...

  7. Prism框架研究(二)

    首先在介绍本节内容之前,首先来看看官方文档来如何描述Prism 应用的初始化吧!A Prism application requires registration and configuration ...

  8. python数学第七天【期望的性质】

  9. python数据结构与算法第十二天【快速排序】

    1. 原理如图所示: 2.代码实现 def quick_sort(alist, start, end): """快速排序""" # 递归的退 ...

  10. 华硕X99-A II 安装使用 志强 XEON E5-1603 v4

    刚开始无法启动,Debug灯的数字不停的轮回变换,后来把XMP开关关闭后,就能正常启动了.如果不行,就多关机几次,一般3次以上应该就可以启动开了.之后就能正常使用了.