P4949 最短距离(基环树+树链剖分)
题目
做法
先把非树边提出来
查询\((x,y)\)的最短距离就分类查询:树上\((x,y)\)距离,经过非树边距离
带边权查询链长,一个烂大街的套路:树链剖分,节点维护树边距离
待修改随便搞搞就行
Code
#include<bits/stdc++.h>
typedef int LL;
const LL maxn=3e5+9;
inline LL Read(){
LL x(0),f(1); char c=getchar();
while(c<'0' || c>'9'){
if(c=='-') f=-1; c=getchar();
}
while(c>='0' && c<='9'){
x=(x<<3)+(x<<1)+c-'0'; c=getchar();
}
return x*f;
}
struct node{
LL to,nxt,d;
}dis[maxn];
LL num;
LL head[maxn];
inline void Add(LL u,LL v,LL w){
dis[++num]=(node){v,head[u],w}; head[u]=num;
}
struct E{
LL u,v,w;
}e[maxn];
LL n,m;
LL n_tree,n_u,n_v,tim,n_d;
LL dep[maxn],size[maxn],visit[maxn],fa[maxn],val[maxn],bel[maxn],son[maxn],dx[maxn],id[maxn],top[maxn];
void Dfs1(LL u,LL f){
dep[u]=dep[f]+1;
size[u]=1; visit[u]=true;
for(LL i=head[u];i;i=dis[i].nxt){
LL v(dis[i].to); if(v==f) continue;
if(visit[v]){
n_tree=i+1>>1; n_u=u; n_v=v; n_d=dis[i].d;
continue;
}
Dfs1(v,u); size[u]+=size[v];
fa[v]=u; val[v]=dis[i].d; bel[i+1>>1]=v;
if(size[son[u]]<size[v]) son[u]=v;
}
}
void Dfs2(LL u,LL up){
dx[++tim]=u; id[u]=tim;
top[u]=up;
if(son[u]) Dfs2(son[u],up);
for(LL i=head[u];i;i=dis[i].nxt){
LL v(dis[i].to); if(v==fa[u] || v==son[u] || (i+1>>1)==n_tree) continue;
Dfs2(v,v);
}
}
struct Bit{
LL t[maxn];
inline LL Lowbit(LL x){
return x&-x;
}
inline void Add(LL x,LL val){
for(;x<=n;x+=Lowbit(x)) t[x]+=val;
}
inline LL Qy(LL x){
LL ret(0);
for(;x;x-=Lowbit(x)) ret+=t[x];
return ret;
}
inline LL Query(LL l,LL r){
return Qy(r)-Qy(l-1);
}
}Bt;
inline LL Query(LL x,LL y){
LL ret(0);
LL fx(top[x]),fy(top[y]);
while(fx!=fy){
if(dep[fx]>=dep[fy]){
ret+=Bt.Query(id[fx],id[x]); x=fa[fx];
}else{
ret+=Bt.Query(id[fy],id[y]); y=fa[fy];
}
fx=top[x]; fy=top[y];
}
if(dep[x]<=dep[y])
ret+=Bt.Query(id[x],id[y])-val[x];
else
ret+=Bt.Query(id[y],id[x])-val[y];
return ret;
}
int main(){
n=Read(); m=Read();
for(LL i=1;i<=n;++i){
LL u(Read()),v(Read()),w(Read());
Add(u,v,w); Add(v,u,w);
e[i]=(E){u,v,w};
}
Dfs1(1,0); Dfs2(1,1);
for(LL i=1;i<=n;++i)
Bt.Add(id[i],val[i]);
while(m--){
LL op(Read()),x(Read()),y(Read());
if(op==1){
if(x==n_tree){
n_d=y;
continue;
}
LL v(bel[x]);
Bt.Add(id[v],-val[v]);
Bt.Add(id[v],val[v]=y);
}else{
printf("%d\n",std::min(Query(x,y),std::min(Query(x,n_u)+Query(y,n_v)+n_d,Query(x,n_v)+Query(y,n_u)+n_d)));
}
}
return 0;
}
P4949 最短距离(基环树+树链剖分)的更多相关文章
- 线段树&数链剖分
傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...
- [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分
题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...
- UOJ#30/Codeforces 487E Tourists 点双连通分量,Tarjan,圆方树,树链剖分,线段树
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ30.html 题目传送门 - UOJ#30 题意 uoj写的很简洁.清晰,这里就不抄一遍了. 题解 首先建 ...
- BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP
题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...
- CF487E Tourists 圆方树、树链剖分
传送门 注意到我们需要求的是两点之间所有简单路径中最小值的最小值,那么对于一个点双联通分量来说,如果要经过它,则一定会经过这个点双联通分量里权值最小的点 注意:这里不能缩边双联通分量,样例\(2\)就 ...
- 2019.01.08 codeforces 1009F. Dominant Indices(长链剖分)
传送门 长链剖分模板题. 题意:给出一棵树,设fi,jf_{i,j}fi,j表示iii的子树中距离点iii距离为jjj的点的个数,现在对于每个点iii要求出使得fif_ifi取得最大值的那个jjj ...
- 【LOJ】#3014. 「JOI 2019 Final」独特的城市(长链剖分)
LOJ#3014. 「JOI 2019 Final」独特的城市(长链剖分) 显然我们画一条直径,容易发现被统计的只可能是直径某个距离较远的端点到这个点的路径上的值 用一个栈统计可以被统计的点,然后我们 ...
- BZOJ 1758 / Luogu P4292 [WC2010]重建计划 (分数规划(二分/迭代) + 长链剖分/点分治)
题意 自己看. 分析 求这个平均值的最大值就是分数规划,二分一下就变成了求一条长度在[L,R]内路径的权值和最大.有淀粉质的做法但是我没写,感觉常数会很大.这道题可以用长链剖分做. 先对树长链剖分. ...
- hdu 6393 Traffic Network in Numazu (树链剖分+线段树 基环树)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6393 思路:n个点,n条边,也就是基环树..因为只有一个环,我们可以把这个环断开,建一个新的点n+1与之相 ...
随机推荐
- centos7 禁用每次sudo 需要输入密码
安装完centos7后,默认没有启用sudo,首先应该是对sudo进行设置.sudo的作用就是使当前非root用户在使用没有权限的命令 时,直接在命令前加入sudo,在输入自己当前用户的密码就可以完成 ...
- (转)git使用教程
git基础使用:http://geek.csdn.net/news/detail/77455 github介绍:http://stormzhang.com/github/2016/05/25/lear ...
- java.lang.NoSuchMethodException: <init> [class android.content.Context, interface androidutil.Attri
<pre name="code" class="java"><span style="font-size:24px;"&g ...
- 【BZOJ4550】小奇的博弈 博弈论
[BZOJ4550]小奇的博弈 Description 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色.最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同. 小 ...
- 【BZOJ2208】[Jsoi2010]连通数 DFS
[BZOJ2208][Jsoi2010]连通数 Description Input 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i行第j列的1表示顶点i到j有边,0则表示 ...
- LeetCode 学习
1.整数反转 题目:给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 思路:把最后的一位提取出来,放到新的容器前面,反复进行上面的操作,同时也要判断是否会导致溢出 class ...
- Java——BeanUtils基本用法
为了操作JavaBean的属性,sun公司自己写了一套内省的api(在Java.beans.*)中,但是我们发现操作起来还是比较复杂的,所以apache公司就自己写了一套api替代了它,大大方便了开发 ...
- ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry ’1′ for key
当我用SQLyog尝试修改已有记录的mysql数据表的主键为自动增长时,报出以下错误 ALTER TABLE causes auto_increment resequencing, resulting ...
- numpy.random.random & numpy.ndarray.astype & numpy.arange
今天看到这样一句代码: xb = np.random.random((nb, d)).astype('float32') #创建一个二维随机数矩阵(nb行d列) xb[:, 0] += np.aran ...
- 基于UDP的套接字、粘包问题
一.基于UDP的套接字 UDP服务端 ss = socket() #创建一个服务器的套接字 ss.bind() #绑定服务器套接字 inf_loop: #服务器无限循环 cs = ss.recvfro ...