【dfs序】【set】bzoj3991 [Sdoi2015]寻宝游戏
在考试代码的基础上稍微改改就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]寻宝游戏的更多相关文章
- [BZOJ3991][SDOI2015]寻宝游戏
[BZOJ3991][SDOI2015]寻宝游戏 试题描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择 ...
- CH#56C 异象石 和 BZOJ3991 [SDOI2015]寻宝游戏
异象石 CH Round #56 - 国庆节欢乐赛 描述 Adera是Microsoft应用商店中的一款解谜游戏. 异象石是进入Adera中异时空的引导物,在Adera的异时空中有一张地图.这张地图上 ...
- BZOJ3991 [SDOI2015]寻宝游戏 【dfs序 + lca + STL】
题目 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路 ...
- [bzoj3991][SDOI2015]寻宝游戏_树链的并_倍增lca_平衡树set
寻宝游戏 bzoj-3991 SDOI-2015 题目大意:题目链接. 注释:略. 想法:我们发现如果给定了一些点有宝物的话那么答案就是树链的并. 树链的并的求法就是把所有点按照$dfs$序排序然后相 ...
- bzoj3991 [SDOI2015]寻宝游戏 树链的并
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3991 题解 貌似这个东西叫做树链的并,以前貌似写过一个类似的用来动态维护虚树. 大概就是最终的 ...
- bzoj3991: [SDOI2015]寻宝游戏--DFS序+LCA+set动态维护
之前貌似在hdu还是poj上写过这道题. #include<stdio.h> #include<string.h> #include<algorithm> #inc ...
- bzoj3991 [Sdoi2015]寻宝游戏 set动态维护虚树+树链求并
题目大意:支持多次操作,增加或删除一个关键点 动态维护虚树边权和*2 分析:可以用树链求并的方法,最后减去虚树的根到1距离 注意到树链求并是所有点到根距离-所有dfn序相邻两点的LCA到根距离 找df ...
- 【BZOJ3991】[SDOI2015]寻宝游戏 树链的并+set
[BZOJ3991][SDOI2015]寻宝游戏 Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩 ...
- bzoj 3991: [SDOI2015]寻宝游戏 虚树 set
目录 题目链接 题解 代码 题目链接 bzoj 3991: [SDOI2015]寻宝游戏 题解 发现每次答案就是把虚树上的路径*2 接在同一关键点上的点的dfs序是相邻的 那么用set动态维护dfs序 ...
随机推荐
- 深入理解Java虚拟机—内存管理机制
前面说过了类的加载机制,里面讲到了类的初始化中时用到了一部分内存管理的知识,这里让我们来看下Java虚拟机是如何管理内存的. 先让我们来看张图 有些文章中对线程隔离区还称之为线程独占区,其实是一个意思 ...
- JSOI2004 平衡点 / 吊打XXX [模拟退火]
题目描述 如图:有n个重物,每个重物系在一条足够长的绳子上.每条绳子自上而下穿过桌面上的洞,然后系在一起.图中X处就是公共的绳结.假设绳子是完全弹性的(不会造成能量损失),桌子足够高(因而重物不会垂到 ...
- 关于MyBatis的collection集合中只能取到一条数据的问题
问题:在涉及多表查询的时候,使用collection元素来映射集合属性时,出现了只能查询到一条数据的情况,但用sql语句在数据库中查询会有多条记录. 解决:如果两表联查,主表和明细表的主键都是id的话 ...
- centos7.6升级ssh7.9、安装PHP7.2、Nginx1.15.9、PHP加密扩展php_screw1.5
1.centos7 安装PHP7.2版本 #查询是否安装过php yum list installed | grep php yum provides php #移除php yum remove ph ...
- mysql root设置密码 linux
成功方案 mysqld_safe --user=mysql --skip-grant-tables --skip-networking & [root@localhost ~]# mysql ...
- django+apache部署
参考:http://blog.csdn.net/rongyongfeikai2/article/details/13093555/ 参考:http://blog.csdn.net/yingmutong ...
- 【Shell 编程基础第二部分】Shell里的流程控制、Shell里的函数及脚本调试方法!
http://blog.csdn.net/xiaominghimi/article/details/7603003 本站文章均为李华明Himi原创,转载务必在明显处注明:转载自[黑米GameDev街区 ...
- 【Shell 编程基础第一部分】第一个Shell脚本HelloShell及一些简单的Shell基础书写与概念;
http://blog.csdn.net/xiaominghimi/article/details/7603000 本站文章均为李华明Himi原创,转载务必在明显处注明:转载自[黑米GameDev街区 ...
- Linux终端彩色打印+终端进度条【转】
转自:https://my.oschina.net/jcseg/blog/178047 开发的一个应用程序选择了终端界面, 为了使软件稍微好看些, 研究下Linux终端的彩色打印, 并且基于这个彩色打 ...
- Tomcat下载安装及常见问题解决办法
一.Tomcat的下载: 下载地址:http://tomcat.apache.org/ 下载Tomcat6.0(在左侧的Download下,考虑到稳定性现在企业大部分还在用Tomcat6.0) (1) ...