「CF838B」 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的更多相关文章
- 「干货」面试官问我如何快速搜索10万个矩形?——我说RBush
「干货」面试官问我如何快速搜索10万个矩形?--我说RBUSH 前言 亲爱的coder们,我又来了,一个喜欢图形的程序员,前几篇文章一直都在教大家怎么画地图.画折线图.画烟花,难道图形就是这样嘛,当 ...
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
- 「C++」理解智能指针
维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...
- 「JavaScript」四种跨域方式详解
超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...
- 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management
写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...
- 「2014-3-18」multi-pattern string match using aho-corasick
我是擅(倾)长(向)把一篇文章写成杂文的.毕竟,写博客记录生活点滴,比不得发 paper,要求字斟句酌八股结构到位:风格偏杂文一点,也是没人拒稿的.这么说来,arxiv 就好比是 paper 世界的博 ...
- 「2014-3-17」C pointer again …
记录一个比较基础的东东-- C 语言的指针,一直让人又爱又恨,爱它的人觉得它既灵活又强大,恨它的人觉得它太过于灵活太过于强大以至于容易将人绕晕.最早接触 C 语言,还是在刚进入大学的时候,算起来有好些 ...
随机推荐
- Servlet 使用ServletConfig对象来配置Servlet
ServletContext和ServletConfig的关联 相同点: 1.都可以用来配置Servlet 2.都可以写在web.xml中. 区别点: 1.ServletContext对象,对于所有的 ...
- nginx强制使用https访问(http跳转到https)
Nginx 的 Location 从零开始配置 - 市民 - SegmentFault 思否https://segmentfault.com/a/1190000009651161 nginx配置loc ...
- 给input标签添加默认提示文字
<input name="username" placeholder="请输入用户名" /> placeholder = "提示文字&qu ...
- 解决ssh ltt3.bg.cn 'jps' bash: jps: command not found 问题
>>提君博客原创 http://www.cnblogs.com/tijun/ << linux 上我用hadoop用户配置好SSH后,运行 ssh ltt3.bg.cn ' ...
- js 解决中文乱码的问题
1.对象 request response 对象setCharacterEncoding=UTF-8 1 <%@ page language="java" contentTy ...
- Django--ORM 多表查询
一 . 建立外键 一对一建立外键 外键名称 = models.OneToOneField(to='要连接的类名', to_field='字段') 一对多建立外键 外键名称 = models.Forei ...
- 新版本macos无法安装mysql-python包
在更新了macos之后就发现无法正确安装python-mysql包了. 上网查阅了一下应该是c库或者osx的基础工具变动带来的问题.看到很多解决办法说使用pymysql,拜托我问的是如何安装pytho ...
- EmpireCMS的使用
1.下载安装empirecms 下载完成后解压将upload目录整体上传到服务器,并更名为empirecms_test 更改目录文件的权限: chmod -R 777 empirecms_test 配 ...
- 在delphi中生成GUID
什么是 GUID ? 全球唯一标识符 (GUID) 是一个字母数字标识符,用于指示产品的唯一性安装.在许多流行软件应用程序(例如 Web 浏览器和媒体播放器)中,都使用 GUID. GUID 的格式为 ...
- java 中的Collection
/* *一. Collection?-------->容器! * * 1.来源于java.util包 非常实用的数据结构! * *二. 方法? * * void clear()删除集合中所有元素 ...