2019 ICPC上海网络赛 A 题 Lightning Routing I (动态维护树的直径)
题目:
给定一棵树, 带边权。
现在有2种操作:
1.修改第i条边的权值。
2.询问u到其他一个任意点的最大距离是多少。
题解:
树的直径可以通过两次 dfs() 的方法求得。换句话说,到任意点最远的点,一定是直径的某个端点(反证法)。
• 因此原问题转化为动态维护直径,然后再支持询问两个点的距离,后者可以 dfs 序 + lca + 树状数组。
参考代码:
#include<bits/stdc++.h>
#define lowbit(x) (x&-x)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mkp make_pair
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=;
const int INF=<<;
const int maxn=1e5+;
struct Edge{
int u,v,w;
} eg[maxn];
vector<pii> edge[maxn];
int n,q,tin[maxn],tout[maxn],rid[maxn],tot; namespace hld{
//树状数组
struct BIT{
ll a[maxn];
inline void update(int i,int x)
{
while(i<=n)
a[i]+=x,i+=lowbit(i);
}
inline void update(int l,int r,int x)
{
update(l,x); update(r+,-x);
}
inline ll query(int i)
{
ll res=;
while(i) res+=a[i],i-=lowbit(i);
return res;
}
} bit;
//树链剖分
int siz[maxn],dep[maxn],fa[maxn],son[maxn],top[maxn];
void dfs(int u,int f)
{
tin[u]=++tot; rid[tot]=u;
dep[u]=dep[f]+; fa[u]=f; siz[u]=; son[u]=;
int m=-;
for(auto&x:edge[u])
{
int v=x.first;
if(v==f) continue;
dfs(v,u);
bit.update(tin[v],tout[v],x.second);//节点到根的距离
siz[u]+=siz[v];
if(siz[v]>m) son[u]=v,m=siz[v];
}
tout[u]=tot;
}
void dfs(int u,int f,int tp)
{
top[u]=tp;
if(!son[u]) return;
dfs(son[u],u,tp);
for(auto&x:edge[u])
{
int v=x.first;
if(v==f||v==son[u]) continue;
dfs(v,u,v);
}
}
void build() //树链剖分
{
dfs(,);dfs(,,);
}
int qlca(int u,int v)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
u=fa[top[u]];
}
return dep[u]<dep[v]?u:v;
}
ll qdis(int u,int v)
{
ll r=bit.query(tin[u])+bit.query(tin[v]);
int l=qlca(u,v);
return r-2ll*bit.query(tin[l]);
}
}
using hld::qdis;
//线段树+树状数组动态维护树直径
struct Node{
int u,v;
ll d;
} tr[maxn<<];
void pushup(int rt)
{
tr[rt]=tr[rt<<].d>tr[rt<<|].d ? tr[rt<<]:tr[rt<<|];
int x=tr[rt<<].u,y=tr[rt<<].v;
int u=tr[rt<<|].u,v=tr[rt<<|].v;
ll tot;
if((tot=qdis(x,u))>tr[rt].d) tr[rt]=(Node){x,u,tot};
if((tot=qdis(x,v))>tr[rt].d) tr[rt]=(Node){x,v,tot};
if((tot=qdis(y,u))>tr[rt].d) tr[rt]=(Node){y,u,tot};
if((tot=qdis(y,v))>tr[rt].d) tr[rt]=(Node){y,v,tot};
}
void build(int l,int r,int rt)
{
if(l==r)
{
int u=rid[l];
tr[rt]=(Node){u,u,};
return ;
}
int m=(l+r)/;
build(lson); build(rson);
pushup(rt);
}
void update(int L,int R,int l,int r,int rt)
{
if(L<=l && r<=R) return ;
int m=(l+r)/;
if(L<=m) update(L,R,lson);
if(R>m) update(L,R,rson);
pushup(rt);
} int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)
{
scanf("%d%d%d",&eg[i].u,&eg[i].v,&eg[i].w);
edge[eg[i].u].push_back({eg[i].v,eg[i].w});
edge[eg[i].v].push_back({eg[i].u,eg[i].w});
}
hld::build(); //树链剖分
build(,n,); scanf("%d",&q);
char op[];
int e,v,w;
for(int i=;i<=q;++i)
{
scanf("%s",op);
if(op[]=='C')
{
scanf("%d%d",&e,&w);
int u=eg[e].u,v=eg[e].v,ww=eg[e].w;
if(hld::fa[v]!=u) swap(u,v);
hld::bit.update(tin[v],tout[v],w-ww);
eg[e].w=w;
update(tin[v],tout[v],,n,);
}
else if(op[]=='Q')
{
scanf("%d",&v);
int x=tr[].u,y=tr[].v;
printf("%lld\n",max(qdis(x,v),qdis(y,v)));
}
}
return ;
}
2019 ICPC上海网络赛 A 题 Lightning Routing I (动态维护树的直径)的更多相关文章
- Peekaboo(2019年上海网络赛K题+圆上整点)
目录 题目链接 题意 思路 代码 题目链接 传送门 题意 你的位置在\(O(0,0)\),\(A\)的位置为\((x_1,y_1)\),\(B\)的位置为\((x_2,y_2)\),现在已知\(a=O ...
- 2019 ICPC南昌网络赛 B题
英雄灭火问题忽略了一点丫 一个超级源点的事情,需要考虑周全丫 2 #include<cstdio> #include<cstring> #include<queue> ...
- 2019 ICPC南京网络赛 F题 Greedy Sequence(贪心+递推)
计蒜客题目链接:https://nanti.jisuanke.com/t/41303 题目:给你一个序列a,你可以从其中选取元素,构建n个串,每个串的长度为n,构造的si串要满足以下条件, 1. si ...
- 2019 ICPC 南昌网络赛
2019 ICPC 南昌网络赛 比赛时间:2019.9.8 比赛链接:The 2019 Asia Nanchang First Round Online Programming Contest 总结 ...
- 2019 ICPC 上海区域赛总结
2019上海区域赛现场赛总结 补题情况(以下通过率为牛客提交): 题号 标题 已通过代码 通过率 我的状态 A Mr. Panda and Dominoes 点击查看 5/29 未通过 B Prefi ...
- Magic Master(2019年南昌网络赛E题+约瑟夫环)
目录 题目链接 题意 思路 代码 题目链接 传送门 题意 初始时你有\(n\)张牌(按顺序摆放),每一次操作你将顶端的牌拿出,然后按顺序将上面的\(m\)张牌放到底部. 思路 首先我们发下拿走\(1\ ...
- 计蒜客 2019南昌邀请网络赛J Distance on the tree(主席树)题解
题意:给出一棵树,给出每条边的权值,现在给出m个询问,要你每次输出u~v的最短路径中,边权 <= k 的边有几条 思路:当时网络赛的时候没学过主席树,现在补上.先树上建主席树,然后把边权交给子节 ...
- 2019上海网络赛B题(差分 + 离散化 or 差分 + 思维)
这题.....队里都没怎么训练差分,导致败北...写了一堆线段树嘤嘤嘤,到最后也是超时,比赛结束后看到了差分的思想于是就去学了一手. 其实了解差分思想的一眼就能看出来是差分了.但是如果对n差分的话很明 ...
- 2019年icpc上海网络赛 B Light bulbs (分块、差分)
https://nanti.jisuanke.com/t/41399 题目大意: 有n个灯,m次操作,每次修改[l,r]内的灯,(off - on ,on - off),问最后有几盏灯亮着. 换种说法 ...
随机推荐
- Linux软件包管理和磁盘管理实践
一.自建yum仓库,分别为网络源和本地源 本地yum仓库的搭建就是以下三个步骤: 创建仓库目录结构 上传相应的包到目录下,或者直接挂载光盘也行,如果挂载光盘,第三步就可以省略,因为光盘默认里有repo ...
- 用c语言打印一个三角形
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<string.h>#include<stdlib.h&g ...
- nyoj 596-谁是最好的Coder (greater, less)
596-谁是最好的Coder 内存限制:64MB 时间限制:1000ms 特判: No 通过数:15 提交数:28 难度:0 题目描述: 计科班有很多Coder,帅帅想知道自己是不是综合实力最强的co ...
- win10添加启动项目
Win10启动文件夹一般位于C:\ProgramData\Microsoft\Windows\Start Menu(开始菜单)\Programs(程序)\StartUp(启动)目录,我们主要讲希望添加 ...
- hopper反汇编工具的逆向伪代码功能并不理想
hopper的逆向代码功能并不如想象中那么好,尤其是在逆向c++代码时.对于从ObjC进入iOS开发又不太清楚运行时的人员来说,hopper可以将反汇编码输出成[obj selector:what]这 ...
- vim常用命令集合(精心整理)
vim编辑器身为一个强大的linux平台编辑器,我就不多说他强大之处了,直接来简述下常用命令,提高自己使用编辑器的效率. 然后就先说下vim编辑器的模式,有的地方说三种,有的地方说两种,教程是按照两种 ...
- tomcat-9.0.20缓存空间不足
问题2:启动时候报这样的警告:警告 [main] org.apache.catalina.webresources.Cache.getResource 无法将位于[/WEB-INF/classes/t ...
- Alibaba Nacos 学习(五):K8S Nacos搭建,使用nfs
Alibaba Nacos 学习(一):Nacos介绍与安装 Alibaba Nacos 学习(二):Spring Cloud Nacos Config Alibaba Nacos 学习(三):Spr ...
- GitHub上优秀的开源项目(转载)
转载出处:https://github.com/Trinea/android-open-project 第一部分 个性化控件(View) 主要介绍那些不错个性化的 View,包括 ListView.A ...
- 使用lib-flexible.js适配移动端UI设计750px设计图
最近在和设计沟通关于设计图尺寸大小和前端实际页面尺寸大小不一致的情况,我们的UI设计是使用的iPone6的,(iphone6: 375px*667px 实际像素:750px*1334px)如果 ...