B. Diverging Directions

题意

给出一个n个点2n-2条边的有向图。n-1条指向远离根方向的边形成一棵树,还有n-1条从非根节点指向根节点的边。

q次操作,1修改第x条边权值为y,2询问,求u到v的最短距离。

题解

在前n-1条边上dfs得到dfs序。

用线段树维护从根到区间里的点的最短距离,和从根到区间里的点再回去的最短距离。

修改第一条边的边权时,就修改了根到这条边指向的点为根的子树里每个点的距离。x为根的子树的点dfs序为L[x]~R[x]。

修改第二种边的边权时,只影响根到这条边出发点再回去的最短距离。

查询时,如果u是v的祖先,最短距离就是根到v的距离减去根到u的距离;不是祖先时,那就是从u为根的子树里的点回到根的最短距离加上根到v的距离。

代码

#include <bits/stdc++.h>
#define N 1<<18
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a)) using namespace std; struct SegTree{
int n;
ll tree[N<<2],lazy[N<<2];
void init(int _n){
n=_n;
mem(tree,0);
mem(lazy,0);
}
void pushdown(int node){
lazy[node<<1]+=lazy[node];
tree[node<<1]+=lazy[node];
lazy[node<<1|1]+=lazy[node];
tree[node<<1|1]+=lazy[node];
lazy[node]=0;
}
void update(int node,int l,int r,int L,int R,ll value){
if(L>R || l>R || r<L) return;
if(L<=l && r<=R){
tree[node]+=value;
lazy[node]+=value;
return;
}
pushdown(node);
update(node<<1,l,l+r>>1,L,R,value);
update(node<<1|1,(l+r>>1)+1,r,L,R,value); tree[node]=min(tree[node<<1],tree[node<<1|1]);
}
ll query(int node,int l,int r,int L,int R){
if(L>R || l>R || r<L) return numeric_limits < ll > ::max();
if(L<=l && r<=R){
return tree[node];
}
pushdown(node);
return min(query(node<<1,l,l+r>>1,L,R),
query(node<<1|1,(l+r>>1)+1,r,L,R));
}
void update(int L,int R,ll value){
update(1,1,n,L,R,value);
}
ll query(int L,int R){
return query(1,1,n,L,R);
}
}from_root,from_root_and_back; struct Edge{
int to,next,w;
}e[N];
int head[N],cnt;
void add(int u,int v,int w){
e[++cnt]=(Edge){v,head[u],w};
head[u]=cnt;
}
int from[N<<1]; int L[N],R[N],idx;
ll dis[N];
void dfs(int x,int fa){
L[x]=R[x]=++idx;
for(int i=head[x];i;i=e[i].next){
int v=e[i].to;
if(v!=fa){
dis[v]=dis[x]+e[i].w;
dfs(v,x);
R[x]=R[v];
}
}
} ll dep(int x){
return from_root.query(L[x],L[x]);
} ll back[N];
int main(){
int n,q;
scanf("%d%d", &n, &q);
int u,v,w;
for(int i=1;i<n;++i){
scanf("%d%d%d", &u, &v, &w);
add(u,v,w);
from[i]=u;
}
for(int i=1;i<n;++i){
scanf("%d%d%d", &u, &v, &w);
back[u]=w;
from[i+n-1]=u;
} from_root.init(n);
from_root_and_back.init(n); dfs(1,0); for(int i=1;i<=n;++i){
from_root.update(L[i],L[i],dis[i]);
from_root_and_back.update(L[i],L[i],dis[i]+back[i]);
} while(q--) {
int o,x,y;
scanf("%d%d%d", &o, &x, &y);
if(o&1) {
if(x<n) {
int v=e[x].to,u=from[x],d=y-dep(v)+dep(u);
from_root.update(L[v],R[v],d);
from_root_and_back.update(L[v],R[v],d);
}
else {
int u=from[x],d=y-back[u];back[u]=y;
from_root_and_back.update(L[u],L[u],d);
}
}
else {
if(L[x]<=L[y]&&R[y]<=R[x])
printf("%lld\n", dep(y)-dep(x));
else
printf("%lld\n",from_root_and_back.query(L[x],R[x])-dep(x)+dep(y));
}
}
return 0;
}

「CF838B」 Diverging Directions的更多相关文章

  1. 「干货」面试官问我如何快速搜索10万个矩形?——我说RBush

    「干货」面试官问我如何快速搜索10万个矩形?--我说RBUSH 前言 亲爱的coder们,我又来了,一个喜欢图形的程序员‍,前几篇文章一直都在教大家怎么画地图.画折线图.画烟花,难道图形就是这样嘛,当 ...

  2. 「译」JUnit 5 系列:条件测试

    原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...

  3. 「译」JUnit 5 系列:扩展模型(Extension Model)

    原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...

  4. JavaScript OOP 之「创建对象」

    工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...

  5. 「C++」理解智能指针

    维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...

  6. 「JavaScript」四种跨域方式详解

    超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...

  7. 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management

    写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...

  8. 「2014-3-18」multi-pattern string match using aho-corasick

    我是擅(倾)长(向)把一篇文章写成杂文的.毕竟,写博客记录生活点滴,比不得发 paper,要求字斟句酌八股结构到位:风格偏杂文一点,也是没人拒稿的.这么说来,arxiv 就好比是 paper 世界的博 ...

  9. 「2014-3-17」C pointer again …

    记录一个比较基础的东东-- C 语言的指针,一直让人又爱又恨,爱它的人觉得它既灵活又强大,恨它的人觉得它太过于灵活太过于强大以至于容易将人绕晕.最早接触 C 语言,还是在刚进入大学的时候,算起来有好些 ...

随机推荐

  1. 01-JavaScript介绍

    JavaScript价绍 1.引言 Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) ...

  2. sql 表值函数与标量值函数

    写sql存储过程经常需要调用一些函数来使处理过程更加合理,也可以使函数复用性更强,不过在写sql函数的时候可能会发现,有些函数是在表值函数下写的有些是在标量值下写的,区别是表值函数只能返回一个表,标量 ...

  3. hibernate 关于hbm.xml编写的总结

    在Hibernate中,各表的映射文件….hbm.xml可以通过工具生成,例如在使用MyEclipse开发时,它提供了自动生成映射文件的工具.本节简单的讲述一下这些配置文件的配置. 配置文件的基本结构 ...

  4. 【kindle笔记】之 《恶意》-2018-4-20

    [kindle笔记]读书记录-总 在答辩和考试和各种大作业的重压以及两天后全校停电的巨大挤压中,一口气读完了恶意这本书. 这本书是我读的东野圭吾的第二本书.第一本是心心念念的<解忧杂货店> ...

  5. maven用框架编写网页运行出现HTTP Status 500 - Unable to compile class for JSP

    利用maven整合框架的时候,通过浏览器访问时,如果出现  HTTP 500-Unable to compile class for JSP 的错误,应该怎么解决呢? 之前在网上看了好多人的解决方案. ...

  6. Oracle RMAN备份与还原

    RMAN在数据库服务器的帮助下实现数据库文件.控制文件.数据库文件与控制文件的映像副本.归档日志文件.数据库服务器参数文件的备份. RMAN的特点: (1) 支持增量备份:传统的exp与expdp备份 ...

  7. Python 爬虫 解析库的使用 --- Beautiful Soup

    知道了正则表达式的相关用法,但是一旦正则表达式写的有问题,得到的可能就不是我们想要的结果了.而且对于一个网页来说,都有一定的特殊结构和层级关系,而且有很多节点都有id或class来做区分,所以借助它们 ...

  8. Java Annotation详解 理解和使用Annotation

    系统中用到了java注解: 查了一下如何使用注解,到底注解是什么: (1)创建方法:MsgTrace Java Class==> 在Create New Class中: name:输入MsgTr ...

  9. APIDOC的使用

    工具名称:APIDOCGit地址:https://github.com/apidoc/apidoc 项目地址:http://apidocjs.com/ 样例项目:http://apidocjs.com ...

  10. Google css & Google fonts

    最近用某开源模板做提案的时候, 抓包工具老是有外部Request. 问题出在某css中有这么一句: @import url(https://fonts.googleapis.com/css?famil ...