LOJ #6145. 「2017 山东三轮集训 Day7」Easy 点分树+线段树
这个就比较简单了~
Code:
#include <cstdio>
#include <algorithm>
#define N 100004
#define inf 1000000000
#define setIO(s) freopen(s".in","r",stdin) // , freopen(s".out","w",stdout)
using namespace std;
int n,edges;
int hd[N],to[N<<1],nex[N<<1],val[N<<1];
void add(int u,int v,int c)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c;
}
namespace tree
{
int size[N],son[N],dep[N],dis[N],fa[N],top[N];
void dfs1(int u,int ff)
{
size[u]=1,fa[u]=ff;
for(int i=hd[u];i;i=nex[i])
if(to[i]!=ff)
{
dis[to[i]]=dis[u]+val[i],dep[to[i]]=dep[u]+1;
dfs1(to[i],u),size[u]+=size[to[i]];
if(size[to[i]]>size[son[u]]) son[u]=to[i];
}
}
void dfs2(int u,int tp)
{
top[u]=tp;
if(son[u]) dfs2(son[u],tp);
for(int i=hd[u];i;i=nex[i])
if(to[i]!=fa[u]&&to[i]!=son[u])
dfs2(to[i],to[i]);
}
int LCA(int x,int y)
{
while(top[x]!=top[y])
dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]];
return dep[x]<dep[y]?x:y;
}
int Dis(int x,int y)
{
return dis[x]+dis[y]-(dis[LCA(x,y)]<<1);
}
};
namespace seg
{
int tot;
#define lson t[x].ls
#define rson t[x].rs
struct Node
{
int ls,rs,min;
}t[N*100];
int newnode()
{
t[++tot].min=inf;
return tot;
}
void pushup(int x)
{
t[x].min=inf;
if(lson) t[x].min=min(t[x].min,t[lson].min);
if(rson) t[x].min=min(t[x].min,t[rson].min);
}
void update(int &x,int l,int r,int p,int v)
{
if(!x) x=newnode();
if(l==r)
{
t[x].min=min(t[x].min,v);
return;
}
int mid=(l+r)>>1;
if(p<=mid) update(lson,l,mid,p,v);
else update(rson,mid+1,r,p,v);
pushup(x);
}
int query(int x,int l,int r,int L,int R)
{
if(!x) return inf;
if(l>=L&&r<=R) return t[x].min;
int mid=(l+r)>>1,re=inf;
if(L<=mid) re=min(re,query(lson,l,mid,L,R));
if(R>mid) re=min(re,query(rson,mid+1,r,L,R));
return re;
}
#undef lson
#undef rson
};
int root,sn;
int size[N],Fa[N],mx[N],vis[N],rt[N];
void getroot(int u,int ff)
{
size[u]=1,mx[u]=0;
for(int i=hd[u];i;i=nex[i])
if(to[i]!=ff&&!vis[to[i]])
getroot(to[i],u),size[u]+=size[to[i]],mx[u]=max(mx[u],size[to[i]]);
mx[u]=max(mx[u],sn-mx[u]);
if(mx[u]<mx[root]) root=u;
}
void dfs(int u,int ff)
{
size[u]=1;
for(int i=hd[u];i;i=nex[i])
if(to[i]!=ff&&!vis[to[i]])
dfs(to[i],u),size[u]+=size[to[i]];
}
void calc(int u,int ff,int dep,int tp)
{
seg::update(rt[tp],1,n,u,dep);
for(int i=hd[u];i;i=nex[i])
if(to[i]!=ff&&!vis[to[i]])
calc(to[i],u,dep+val[i],tp);
}
void prepare(int u)
{
vis[u]=1,calc(u,0,0,u);
for(int i=hd[u];i;i=nex[i])
if(!vis[to[i]])
dfs(to[i],u),root=0,sn=size[to[i]],getroot(to[i],u),Fa[root]=u,prepare(root);
}
int query(int u,int l,int r)
{
int re=seg::query(rt[u],1,n,l,r),U=u;
for(;Fa[u];u=Fa[u])
re=min(re, seg::query(rt[Fa[u]],1,n,l,r)+tree::Dis(U,Fa[u]));
return re;
}
int main()
{
int i,j,m;
// setIO("input");
scanf("%d",&n);
for(i=1;i<n;++i)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c),add(a,b,c),add(b,a,c);
}
tree::dfs1(1,0),tree::dfs2(1,1);
root=0,mx[root]=sn=n,getroot(1,0),prepare(root);
scanf("%d",&m);
for(i=1;i<=m;++i)
{
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",query(x,l,r));
}
return 0;
}
LOJ #6145. 「2017 山东三轮集训 Day7」Easy 点分树+线段树的更多相关文章
- 【loj6145】「2017 山东三轮集训 Day7」Easy 动态点分治+线段树
题目描述 给你一棵 $n$ 个点的树,边有边权.$m$ 次询问,每次给出 $l$ .$r$ .$x$ ,求 $\text{Min}_{i=l}^r\text{dis}(i,x)$ . $n,m\le ...
- #6145. 「2017 山东三轮集训 Day7」Easy 动态点分治
\(\color{#0066ff}{题目描述}\) JOHNKRAM 最近在参加 C_SUNSHINE 举办的聚会. C 国一共有 n 座城市,这些城市由 n−1 条无向道路连接.任意两座城市之间有且 ...
- 「2017 山东三轮集训 Day7」Easy
一棵带边权的树,多次询问 $x$ 到编号为 $[l,r]$ 的点最短距离是多少 $n \leq 100000$ sol: 动态点分治,每层重心维护到所有点的距离 查询的时候在管辖这个点的 log 层线 ...
- Loj #6142. 「2017 山东三轮集训 Day6」A
link: https://loj.ac/problem/6142 推完一波式子之后发现求的是:ΣC(N,i)^2, 其中i是偶数. 然后就可以卢卡斯乱搞了,分奇偶和之前的答案合并就好了233. #i ...
- loj #6138. 「2017 山东三轮集训 Day4」Right
题目: 题解: 暴力一波 \(SG\) 函数可以发现这么一个规律: \(p\) 为奇数的时候 : \(SG(n) = n \% 2\) \(p\) 为偶数的时候 : \(SG(n) = n \% (p ...
- loj #6136. 「2017 山东三轮集训 Day4」Left
题目: 题解: 我们可以发现所有的交换器都是一个位置连接着下一层左侧的排序网络,另一个位置连着另一侧的排序网络. 而下一层是由两个更低阶的排序网络构成的. 两个网络互不干扰.所以我们可以通过第一行和最 ...
- 「2017 山东三轮集训 Day7 解题报告
「2017 山东三轮集训 Day7」Easy 练习一下动态点分 每个点开一个线段树维护子树到它的距离 然后随便查询一下就可以了 注意线段树开大点... Code: #include <cstdi ...
- 「2017 山东三轮集训 Day1」Flair
模拟赛的题 好神仙啊 题面在这里 之前的Solution很蠢 现在已经update.... 题意 有$ n$个商品价格均为$ 1$,您有$ m$种面值的货币,面值为$ C_1..C_m$ 每种物品你有 ...
- 【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.当 ...
随机推荐
- Python使用pycharm导入pymysql
file->setting->project->project interperter,双击右侧出现的pip,弹出安装包,搜索pymysql->选择第一个->Instal ...
- Redis 以及 Python操作Redis
Redis Redis是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis有以下特点: -- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可 ...
- Luogu P5354 [Ynoi2017]由乃的OJ
题目 这题以前叫睡觉困难综合征. 首先我们需要知道起床困难综合征怎么做. 大概就是先用一个全\(0\)和全\(1\)的变量跑一遍处理出每一位\(1\)和\(0\)最后会变成什么. 然后高位贪心:如果当 ...
- 仿优酷项目—orm
仿优酷项目 一.ORM介绍 对象关系映射,把数据库中的表数据(表名.表记录.字段)全部映射到python中. mysql: python: 表名 ---->类名 记录 ----> ...
- redis 学习(14)-- HyperLogLog
HyperLogLog 什么是 HyperLogLog HyperLogLog 是基于 HyperLogLog 算法的一种数据结构,该算法可以在极小空间完成独立数量统计. 在本质上还是字符串类型. 重 ...
- redis 学习(6)-- 集合类型
redis 学习(6)-- 集合类型 set 结构 无序 无重复 集合间操作 set 集合内操作 命令 含义 sadd key memebr1 [member2...] 向集合中添加一个或多个成员 s ...
- 提升scrapy的爬取效率
增加并发: 默认scrapy开启的并发线程为32个,可以适当进行增加.在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100. 降低日志级别 ...
- 07-django项目连接远程mysql数据库
比如电脑a(ip地址为192.168.0.aaa)想要连接访问电脑b(ip地址为192.168.0.bbb)的数据库: 对电脑a(ip地址为192.168.0.aaa): 在项目settings.py ...
- 第十二篇 JavaScript(简称JS) 实现显示与隐藏
JavaScript JavaScript简称JS.JS是脚本语言,它是一种轻量级的编程语言,是可以插入HTML页面的编程代码,几乎所有现代浏览器都是支持的. 理论老师不行,我就抄袭手册上的一些关 ...
- LLVM 词典
#LLVM 词典 ## 本文转自https://github.com/oxnz/clang-user-manual/blob/master/LLVM-Language-Reference-Manual ...