在考试代码的基础上稍微改改就a了……当时为什么不稍微多想想……

插入/删除一个新节点时就把其dfn插入set/从set中删除。

当前的答案就是dfn上相邻的两两节点的距离和,再加上首尾节点的距离。

比较显然?不会证明……

貌似叫“虚树”?

#include<cstdio>
#include<set>
using namespace std;
#define N 100001
typedef long long ll;
set<int>S;
typedef set<int>::iterator ER;
int n,m;
int v[N<<1],first[N],next[N<<1],w[N<<1],en;
void AddEdge(int U,int V,int W)
{
v[++en]=V;
w[en]=W;
next[en]=first[U];
first[U]=en;
}
int top[N],dep[N],fa[N],siz[N],son[N],dfn[N],Map[N];
ll sumv[N],ans;
bool a[N];
void dfs(int U)
{
siz[U]=1;
for(int i=first[U];i;i=next[i])
if(v[i]!=fa[U])
{
fa[v[i]]=U;
dep[v[i]]=dep[U]+1;
sumv[v[i]]=sumv[U]+(ll)w[i];
dfs(v[i]);
siz[U]+=siz[v[i]];
if(siz[v[i]]>siz[son[U]])
son[U]=v[i];
}
}
void df2(int U)
{
dfn[U]=++en;
Map[en]=U;
if(son[U])
{
top[son[U]]=top[U];
df2(son[U]);
}
for(int i=first[U];i;i=next[i])
if(v[i]!=fa[U]&&v[i]!=son[U])
{
top[v[i]]=v[i];
df2(v[i]);
}
}
int lca(int U,int V)
{
while(top[U]!=top[V])
{
if(dep[top[U]]<dep[top[V]])
swap(U,V);
U=fa[top[U]];
}
if(dep[U]>dep[V])
swap(U,V);
return U;
}
ll Query(int U,int V)
{
return sumv[U]+sumv[V]-(sumv[lca(U,V)]<<1);
}
int main()
{
int x,y,z;
scanf("%d%d",&n,&m);
for(int i=1;i<n;++i)
{
scanf("%d%d%d",&x,&y,&z);
AddEdge(x,y,z);
AddEdge(y,x,z);
}
en=0;
top[1]=1;
dfs(1);
df2(1);
for(;m;--m)
{
scanf("%d",&x);
a[x]^=1;
if(a[x])
{
S.insert(dfn[x]);
ER it=S.end(); --it;
ER jt=S.begin();
if(S.size()==0||S.size()==1) ans=0;
if(S.size()==2)
ans=(Query(Map[*jt],Map[*it])<<1);
else if(S.size()>2&&(*jt)==dfn[x])
{
ans+=Query(Map[*jt],Map[*it]);
ER kt=jt; ++kt;
ans+=Query(Map[*jt],Map[*kt]);
ans-=Query(Map[*kt],Map[*it]);
}
else if(S.size()>2&&(*it)==dfn[x])
{
ans+=Query(Map[*jt],Map[*it]);
ER kt=it; --kt;
ans+=Query(Map[*it],Map[*kt]);
ans-=Query(Map[*kt],Map[*jt]);
}
else if(S.size()>2)
{
ER kt=S.find(dfn[x]);
ER lt=kt; --lt;
ER mt=kt; ++mt;
ans+=Query(Map[*lt],Map[*kt]);
ans+=Query(Map[*kt],Map[*mt]);
ans-=Query(Map[*lt],Map[*mt]);
}
}
else
{
ER it=S.end(); --it;
ER jt=S.begin();
if(S.size()==0||S.size()==1) ans=0;
if(S.size()==2)
ans=(Query(Map[*jt],Map[*it])<<1);
else if(S.size()>2&&(*jt)==dfn[x])
{
ans-=Query(Map[*jt],Map[*it]);
ER kt=jt; ++kt;
ans-=Query(Map[*jt],Map[*kt]);
ans+=Query(Map[*kt],Map[*it]);
}
else if(S.size()>2&&(*it)==dfn[x])
{
ans-=Query(Map[*jt],Map[*it]);
ER kt=it; --kt;
ans-=Query(Map[*it],Map[*kt]);
ans+=Query(Map[*kt],Map[*jt]);
}
else if(S.size()>2)
{
ER kt=S.find(dfn[x]);
ER lt=kt; --lt;
ER mt=kt; ++mt;
ans-=Query(Map[*lt],Map[*kt]);
ans-=Query(Map[*kt],Map[*mt]);
ans+=Query(Map[*lt],Map[*mt]);
}
S.erase(dfn[x]);
}
printf("%lld\n",ans);
}
return 0;
}

【dfs序】【set】bzoj3991 [Sdoi2015]寻宝游戏的更多相关文章

  1. [BZOJ3991][SDOI2015]寻宝游戏

    [BZOJ3991][SDOI2015]寻宝游戏 试题描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择 ...

  2. CH#56C 异象石 和 BZOJ3991 [SDOI2015]寻宝游戏

    异象石 CH Round #56 - 国庆节欢乐赛 描述 Adera是Microsoft应用商店中的一款解谜游戏. 异象石是进入Adera中异时空的引导物,在Adera的异时空中有一张地图.这张地图上 ...

  3. BZOJ3991 [SDOI2015]寻宝游戏 【dfs序 + lca + STL】

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

  4. [bzoj3991][SDOI2015]寻宝游戏_树链的并_倍增lca_平衡树set

    寻宝游戏 bzoj-3991 SDOI-2015 题目大意:题目链接. 注释:略. 想法:我们发现如果给定了一些点有宝物的话那么答案就是树链的并. 树链的并的求法就是把所有点按照$dfs$序排序然后相 ...

  5. bzoj3991 [SDOI2015]寻宝游戏 树链的并

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3991 题解 貌似这个东西叫做树链的并,以前貌似写过一个类似的用来动态维护虚树. 大概就是最终的 ...

  6. bzoj3991: [SDOI2015]寻宝游戏--DFS序+LCA+set动态维护

    之前貌似在hdu还是poj上写过这道题. #include<stdio.h> #include<string.h> #include<algorithm> #inc ...

  7. bzoj3991 [Sdoi2015]寻宝游戏 set动态维护虚树+树链求并

    题目大意:支持多次操作,增加或删除一个关键点 动态维护虚树边权和*2 分析:可以用树链求并的方法,最后减去虚树的根到1距离 注意到树链求并是所有点到根距离-所有dfn序相邻两点的LCA到根距离 找df ...

  8. 【BZOJ3991】[SDOI2015]寻宝游戏 树链的并+set

    [BZOJ3991][SDOI2015]寻宝游戏 Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩 ...

  9. bzoj 3991: [SDOI2015]寻宝游戏 虚树 set

    目录 题目链接 题解 代码 题目链接 bzoj 3991: [SDOI2015]寻宝游戏 题解 发现每次答案就是把虚树上的路径*2 接在同一关键点上的点的dfs序是相邻的 那么用set动态维护dfs序 ...

随机推荐

  1. ext radiogroup如何取值和设值

    var radios = Ext.create('Ext.form.Panel', { title: 'RadioGroup Example', width: 300, height: 125, bo ...

  2. POJ1062:昂贵的聘礼(dfs)

    昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 58108   Accepted: 17536 题目链接:http ...

  3. 配置Tomcat时server.xml和content.xml自动还原问题

    当我们在处理中文乱码或是配置数据源时,我们要修改Tomcat下的server.xml和content.xml文件. 但是当我们修改完后重启Tomcat服务器时发现xml文件又被还原了,修改无效果. 为 ...

  4. 7月23号day15总结

    数据清洗完成之后开始编写前端,通过spring框架将清洗后数据库中的数据显示在页面中. 框架的搭建和js的使用都在学习阶段,

  5. Python代码规范

    一:背景 用于规范化ocp python开发,对于使用python开发的程序使用统一的风格,便于代码的维护 二:python风格规范 分号:不要在行尾加分号,也不要用分号将两条命令放在同一行 括号:宁 ...

  6. AWS CLI command example

    1.list ec2 instance-id, instance status, type, ip address, name aws ec2 describe-instances --query ' ...

  7. 我们用CloudStack做什么

    原文地址:http://www.sdfengxi.com/?p=376 我想很多同学会有类似的疑问,就是我配置好了CloudStack或者OpenStack之类的环境之后能够提供什么服务或者应用呢?下 ...

  8. html初探

    HTML HTML是英文Hyper Text Mark-up Language(超文本标记语言)的缩写,他是一种制作万维网页面标准语言(标记).相当于定义统一的一套规则,大家都来遵守他,这样就可以让浏 ...

  9. 【hdu3080】01背包(容量10^7)

    [题意]n个物品,有wi和vi,组成若干个联通块,只能选取一个联通块,问得到m的价值时最小要多少空间(v).n<=50,v<=10^7 [题解] 先用并查集找出各个联通块. 这题主要就是v ...

  10. pandas 读写sql数据库

    如何从数据库中读取数据到DataFrame中? 使用pandas.io.sql模块中的sql.read_sql_query(sql_str,conn)和sql.read_sql_table(table ...