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),问最后有几盏灯亮着. 换种说法 ...
随机推荐
- 使用websocketpp进行websocket通信
websocketpp介绍 websocketpp是一个只有头文件的支持websocket协议的C++开源库,支持websocket客户端和服务器功能,网络传输模块基于boost::asio 提供 s ...
- CAS Server集成QQ登录、新浪微博登录源码及配置文件
转载自素文宅博客:https://blog.yoodb.com/yoodb/article/detail/1446 CAS Server集成QQ第三方登录,CAS Server集成新浪微博第三方登录以 ...
- 深入理解计算机系统 第三章 程序的机器级表示 part3
这周看了刘老师提供的相关视频,以及书中对应的章节“3.7 过程” 这一节分为运行时栈.转移控制.数据传送.栈上的局部存储.寄存器中的局部存储空间和递归过程这 6 个小节 其中前 3 小节看懂了一部分内 ...
- docker swarm 过滤器affinity 限制副本不会出现在同一个节点上
affinity:container!=容器服务名称(可以是正则) 举个例子:stack_ds.yaml # cat stack_dsc.yaml version: '3.0' services: t ...
- hdu 2647 Reward (topsort)
RewardTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- ENS中文文档系列之一 [ ENS介绍 ]
前言 ENS中文文档是由我照ENS英文官方文档翻译而来,其中的一些内容和细节得到了ENS官方团队的指导.文档中包含 “LBB译注” 的地方是译者为了便于读者理解而进行的注释. 未来一段时间,我会在该博 ...
- 022.掌握Pod-Pod升级和回滚
一 deploymentPod升级和回滚 1.1 deployment升级 若Pod是通过Deployment创建的,可以在运行时修改Deployment的Pod定义(spec.template)或镜 ...
- Go 多变量赋值时注意事项
说到多变量赋值时,先计算所有相关值,然后再从左到右依次赋值,但是这个规则不适用于python我们来看一例: package main import "fmt" func main( ...
- Bootstrap3中的affix的使用Demo
<div class="container"> <div class="col-md-3"> <ul class="li ...
- js-程序结构
程序结构: 1.顺序结构(主体结构):自上而下,逐行实行: 2.分支(选择)结构:if语句,if…else, if…else if…else,switch; 3.循环结构:重复某些代码: 分支 ...