/*
给定一棵树,树上会出现宝物,也会有宝物消失
规定如果要收集树上所有宝物,就要选择一个点开始,到每个宝物点都跑一次,然后再回到那个点
现在给定m次修改,每次修改后树上就有一个宝物消失,或者一个宝物出现
请问在这次操作后,按规则跑一次找到所有宝物的最短路径长度 显然按规则跑一次找宝物经过的路径长度,就是从根节点开始dfs一次这些点再回到根节点的路径长度
那么需要将这条路径分解:
将宝物所在点按dfs序依次排列,收尾相接形成一个环
总路径就是环上相邻两点的路径之和
那么每次在环中加入一个点,只要找到环中和其dfs相邻的两个点,加入两条路径即可,删除原来的一条路径即可
每次在环中删掉一个点同理
在增删的过程中保存dfs升序,用set维护结点的dfs即可
*/
#include<bits/stdc++.h>
#include<set>
using namespace std;
#define maxn 100005
#define ll long long
struct Edge{ll to,nxt,w;}edge[maxn<<];
int head[maxn],tot,n,m;
set<int>s;//存储存在宝箱的点的dfs序
set<int>::iterator it;
int cnt,pos[maxn],id[maxn];//每个点的dfs序,dfs序对应的点
ll ans;
void init(){
memset(head,-,sizeof head);
tot=;
}
void addedge(int u,int v,int w){
edge[tot].nxt=head[u];edge[tot].w=w;edge[tot].to=v;head[u]=tot++;
}
void dfs(int u,int pre){
pos[u]=++cnt;id[cnt]=u;
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(v!=pre)dfs(v,u);
}
} int d[maxn],f[maxn][];
ll dep[maxn];
void bfs(){
queue<int>q;
q.push();
d[]=;dep[]=;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=head[x];i!=-;i=edge[i].nxt){
int v=edge[i].to;
if(d[v])continue;
d[v]=d[x]+;
dep[v]=dep[x]+edge[i].w;
f[v][]=x;
for(int k=;k<=;k++)
f[v][k]=f[f[v][k-]][k-];
q.push(v);
}
}
}
ll lca(int u,int v){
int x=u,y=v;
if(d[u]<d[v])swap(u,v);
for(int i=;i>=;i--)
if(d[f[u][i]]>=d[v])u=f[u][i];
if(u==v){
return abs(dep[x]-dep[y]);
}
for(int i=;i>=;i--)
if(f[u][i]!=f[v][i])u=f[u][i],v=f[v][i];
u=f[u][];
return (dep[x]+dep[y]-*dep[u]);
} int flag[maxn];
int L(int x){//返回x左边的结点
it=s.lower_bound(pos[x]);
if(it==s.begin())it=s.end();
--it;
return id[*it];
}
int R(int x){//返回x右边的结点
it=s.lower_bound(pos[x]);
++it;
if(it==s.end())it=s.begin();
return id[*it];
}
ll query(int x){
int mul,left,right;
if(flag[x]==){//往集合里加入结点
flag[x]=mul=;
s.insert(pos[x]);
left=L(x);right=R(x);
}
else {//把集合里的结点删了
flag[x]=;mul=-;
left=L(x);right=R(x);
s.erase(pos[x]);
}
if(s.size()==)return ;
ans+=(ll)mul*(lca(left,x)+lca(x,right)-lca(left,right));
return ans;
}
int main(){
init();
scanf("%d%d",&n,&m);
for(int i=;i<n;i++){
ll u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
dfs(,);//求出dfs序
bfs();//预处理
for(int i=;i<=m;i++){
int x,u,v;
scanf("%d",&x);
printf("%lld\n",query(x));
}
}

bzoj3991 lca+dfs序应用+set综合应用的更多相关文章

  1. 【BZOJ】2819: Nim(树链剖分 / lca+dfs序+树状数组)

    题目 传送门:QWQ 分析 先敲了个树链剖分,发现无法AC(其实是自己弱,懒得debug.手写栈) 然后去学了学正解 核心挺好理解的,$ query(a) $是$ a $到根的异或和. 答案就是$ l ...

  2. 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...

  3. BZOJ3991:寻宝游戏 (LCA+dfs序+树链求并+set)

    小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路上行走 ...

  4. BZOJ3881[Coci2015]Divljak——AC自动机+树状数组+LCA+dfs序+树链的并

    题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...

  5. nowcoder172C 保护 (倍增lca+dfs序+主席树)

    https://www.nowcoder.com/acm/contest/172/C (sbw大佬太强啦 orz) 先把每一个路径(x,y)分成(x,lca),(y,lca)两个路径,然后就能发现,对 ...

  6. Codeforces Gym 101142 G Gangsters in Central City (lca+dfs序+树状数组+set)

    题意: 树的根节点为水源,编号为 1 .给定编号为 2, 3, 4, …, n 的点的父节点.已知只有叶子节点都是房子. 有 q 个操作,每个操作可以是下列两者之一: + v ,表示编号为 v 的房子 ...

  7. HDU 6203 ping ping ping(贪心+LCA+DFS序+BIT)

    ping ping ping Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  8. CH#56C(LCA+dfs序)

    题目传送门 性质是:把节点dfs序以后,异象石按这个序号排序,然后相邻两两求树上距离,这些距离的和除以二就是最小斯坦纳树. 插入删除的具体操作是根据我们上述性质,用一个set维护dfn,比如插入x,则 ...

  9. poj 2763(LCA + dfs序 +树状数组)

    算是模板题了 可以用dfs序维护点到根的距离 注意些LCA的时候遇到MAXM,要-1 #include<cstdio> #include<algorithm> #include ...

随机推荐

  1. axios 在Vue全局引入的方法

    在main.js中: import axios form axios Vue.prototype.$axios = axios 组件中使用: submitFrom () { this.$axios.g ...

  2. netty长链接保存方案

    架构 client router server zk redis 对于router: 保存客户端和服务器对 redis clientid : serverip & port 对于server ...

  3. Python笔记(二)查找重复元素

    一.查找数列重复元素---count() >>> list = [,,,,,,,,,,,] >>> set = set(list) >>> for ...

  4. mysql 8.0 ~ innodb与变量优化

    一  innodb的优化  1 已完全不支持myisam引擎  2 将自增主键的计数器持久化到redo log中.每次计数器发生改变,都会将其写入到redo log中.如果数据库发生重启,InnoDB ...

  5. python编程 之 PyMysql包接口,python中如何使用数据库

    1,环境介绍 要求:使用数据库TESTDB.EMPLOYMENT EMPLOYEE表字段为 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME. 2,基本用法: impo ...

  6. Linux 逻辑卷管理LVM

    LVM概述 Logical Volume Manager,逻辑卷管理 屏蔽了底层磁盘布局,便于动态调整磁盘容量 需要注意:/boot分区用于存放引导文件,不能应用LVM机制 LVM结构 目标:将sdb ...

  7. Datasnap 服务端 (Server)Session 管理 --- 解决 全示例慢(Google)

    Datasnap 服务端 (Server)Session  管理:  http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Server_Side_Ses ...

  8. python 彩色日志配置

    import os import logging import logging.config as log_conf import datetime import coloredlogs log_di ...

  9. HTTP协议06-报文首部

    HTTP报文格式 ​ HTTP协议的请求和响应报文中必定包含HTTP首部.首部内容为客户端和服务器分别处理请求和响应提供所需要的信息. 1)HTTP请求报文 在请求中,HTTP报文由方法.URI.HT ...

  10. 解决python发送multipart/form-data请求上传文件的问题

    服务器接收文件时,有时会使用表单接收的方式,这意味着我们需要使用Python的requests上传表单数据和文件. 常用的方式一般如下: data = { 'name': 'nginx' } file ...