CH#56C 异象石 和 BZOJ3991 [SDOI2015]寻宝游戏
异象石 CH Round #56 - 国庆节欢乐赛
描述
Adera是Microsoft应用商店中的一款解谜游戏。
异象石是进入Adera中异时空的引导物,在Adera的异时空中有一张地图。这张地图上有N个点,有N-1条双向边把它们连通起来。起初地图上没有任何异象石,在接下来的M个时刻中,每个时刻会发生以下三种类型的事件之一:
1. 地图的某个点上出现了异象石(已经出现的不会再次出现);
2. 地图某个点上的异象石被摧毁(不会摧毁没有异象石的点);
3. 向玩家询问使所有异象石所在的点连通的边集的总长度最小是多少。
请你作为玩家回答这些问题。
输入格式
第一行有一个整数N,表示点的个数。
接下来N-1行每行三个整数x,y,z,表示点x和y之间有一条长度为z的双向边。
第N+1行有一个正整数M。
接下来M行每行是一个事件,事件是以下三种格式之一:
+ x 表示点x上出现了异象石
- x 表示点x上的异象石被摧毁
? 表示询问使当前所有异象石所在的点连通所需的边集的总长度最小是多少。
输出格式
对于每个 ? 事件,输出一个整数表示答案。
样例输入
6
1 2 1
1 3 5
4 1 7
4 5 3
6 4 2
10
+ 3
+ 1
?
+ 6
?
+ 5
?
- 6
- 3
?
样例输出
5
14
17
10
数据范围与约定
- 对于30%的数据,1 ≤ n, m ≤ 1000。
- 对于另20%的数据,地图是一条链,或者一朵菊花。
- 对于100%的数据,1 ≤ n, m ≤ 10^5, 1 ≤ x, y ≤ n, x ≠ y, 1 ≤ z ≤ 10^9。
</article>
题解
把有异象石的点按照其DFS序大小写作一个环形序列,该序列中相邻的数的距离之和就是答案的2倍。
用set维护这个序列,用一个变量记录答案,插入or摧毁时在序列中插入or删除数,并更改答案即可。求距离可以用倍增lca。
时间复杂度\(O((n+m)\log n)\)
#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std;
typedef pair<int,int> pii;
co int N=1e5+1;
int n,m,t,f[N][18],dep[N],dfn[N],tot;
vector<pii> e[N];
ll d[N],ans;
set<pii> st;
typedef set<pii>::iterator it;
void dfs(int x){
dfn[x]=++tot;
for(int i=0,y;i<e[x].size();++i){
if(dep[y=e[x][i].first]) continue;
dep[y]=dep[x]+1;
d[y]=d[x]+e[x][i].second;
f[y][0]=x;
for(int j=1;j<=t;++j) f[y][j]=f[f[y][j-1]][j-1];
dfs(y);
}
}
int lca(int x,int y){
if(dep[x]>dep[y]) swap(x,y);
for(int i=t;i>=0;--i)
if(dep[f[y][i]]>=dep[x]) y=f[y][i];
if(x==y) return x;
for(int i=t;i>=0;--i)
if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}
il ll path(int x,int y){
return d[x]+d[y]-2*d[lca(x,y)];
}
il void insert(int x){
st.insert(pii(dfn[x],x));
it l=st.find(pii(dfn[x],x));
l=l==st.begin()?--st.end():--l;
it r=st.find(pii(dfn[x],x));
r=r==--st.end()?st.begin():++r;
ans-=path(l->second,r->second);
ans+=path(l->second,x)+path(x,r->second);
}
il void remove(int x){
it l=st.find(pii(dfn[x],x));
l=l==st.begin()?--st.end():--l;
it r=st.find(pii(dfn[x],x));
r=r==--st.end()?st.begin():++r;
ans-=path(l->second,x)+path(x,r->second);
ans+=path(l->second,r->second);
st.erase(pii(dfn[x],x));
}
int main(){
read(n);
for(int i=1,x,y,z;i<n;++i){
read(x),read(y),read(z);
e[x].push_back(pii(y,z)),e[y].push_back(pii(x,z));
}
t=log(n)/log(2)+1;
dep[1]=1,dfs(1);
for(read(m);m--;){
char s[2];scanf("%s",s);
if(s[0]=='?') printf("%lld\n",ans/2);
else{
int x=read<int>();
s[0]=='+'?insert(x):remove(x);
}
}
return 0;
}
3991: [SDOI2015]寻宝游戏
Time Limit: 40 Sec Memory Limit: 128 MB
Submit: 2219 Solved: 1133
[Submit][Status][Discuss]
Description
小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达。游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路上行走,若走到某个村庄中有宝物,则视为找到该村庄内的宝物,直到找到所有宝物并返回到最初转移到的村庄为止。小B希望评测一下这个游戏的难度,因此他需要知道玩家找到所有宝物需要行走的最短路程。但是这个游戏中宝物经常变化,有时某个村庄中会突然出现宝物,有时某个村庄内的宝物会突然消失,因此小B需要不断地更新数据,但是小B太懒了,不愿意自己计算,因此他向你求助。为了简化问题,我们认为最开始时所有村庄内均没有宝物
Input
第一行,两个整数N、M,其中M为宝物的变动次数。
Output
M行,每行一个整数,其中第i行的整数表示第i次操作之后玩家找到所有宝物需要行走的最短路程。若只有一个村庄内有宝物,或者所有村庄内都没有宝物,则输出0。
Sample Input
1 2 30
2 3 50
2 4 60
2
3
4
2
1
Sample Output
100
220
220
280
HINT
1<=N<=100000
Source
[Submit][Status][Discuss]
HOME
Back
题解
这个每条边要走两次,选他们构成的虚树上的那个点都无所谓。实际上就是上一道题,只不过答案不用除以2.
CH#56C 异象石 和 BZOJ3991 [SDOI2015]寻宝游戏的更多相关文章
- [BZOJ3991][SDOI2015]寻宝游戏
[BZOJ3991][SDOI2015]寻宝游戏 试题描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择 ...
- [bzoj3991][SDOI2015]寻宝游戏_树链的并_倍增lca_平衡树set
寻宝游戏 bzoj-3991 SDOI-2015 题目大意:题目链接. 注释:略. 想法:我们发现如果给定了一些点有宝物的话那么答案就是树链的并. 树链的并的求法就是把所有点按照$dfs$序排序然后相 ...
- CH#56C 异象石
一道LCA 原题链接 先跑一边\(dfs\),求出每个节点的时间戳,如果我们将有异象石的节点按时间戳从小到大的顺序排列,累加相邻两节点之间的距离(首尾相邻),会发现总和就是答案的两倍. 于是我们只需要 ...
- bzoj3991: [SDOI2015]寻宝游戏--DFS序+LCA+set动态维护
之前貌似在hdu还是poj上写过这道题. #include<stdio.h> #include<string.h> #include<algorithm> #inc ...
- bzoj3991 [Sdoi2015]寻宝游戏 set动态维护虚树+树链求并
题目大意:支持多次操作,增加或删除一个关键点 动态维护虚树边权和*2 分析:可以用树链求并的方法,最后减去虚树的根到1距离 注意到树链求并是所有点到根距离-所有dfn序相邻两点的LCA到根距离 找df ...
- 【dfs序】【set】bzoj3991 [Sdoi2015]寻宝游戏
在考试代码的基础上稍微改改就a了……当时为什么不稍微多想想…… 插入/删除一个新节点时就把其dfn插入set/从set中删除. 当前的答案就是dfn上相邻的两两节点的距离和,再加上首尾节点的距离. 比 ...
- BZOJ3991 [SDOI2015]寻宝游戏 【dfs序 + lca + STL】
题目 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路 ...
- bzoj3991 [SDOI2015]寻宝游戏 树链的并
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3991 题解 貌似这个东西叫做树链的并,以前貌似写过一个类似的用来动态维护虚树. 大概就是最终的 ...
- 【BZOJ3991】[SDOI2015]寻宝游戏 树链的并+set
[BZOJ3991][SDOI2015]寻宝游戏 Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩 ...
随机推荐
- centos set up samba
原文中文链接:https://wiki.centos.org/zh/HowTos/SetUpSamba 原文英文链接:https://wiki.centos.org/HowTos/SetUpSamba ...
- 原来还有cookie-free domain这么回事
cookie-free domain的解释:在请求下载静态小图片.静态小文件的时候,浏览器会把它当成普通请求一样,在request的header信息里附加cookie信息. 但实际上,99.99%的静 ...
- Zabbix-Agent 客户端安装配置
1.安装Zabbix官方的yum源 [root@crazy-acong ~]# rpm -ivh http://repo.zabbix.com/zabbix/2.2/rhel/6/x86_64/zab ...
- MySQL 练习 答案
表关系 二.操作表 1.自行创建测试数据 2.查询“生物”课程比“物理”课程成绩高的所有学生的学号: 3.查询平均成绩大于60分的同学的学号和平均成绩: 4.查询所有同学的学号.姓名.选课数.总成绩: ...
- spark0.9.0安装
利用周末的时间安装学习了下最近很火的Spark0.9.0(江湖传言,要革hadoop命,O(∩_∩)O),并体验了该框架下的机器学习包MLlib(spark解决的一个重点就是高效的运行迭代算法),下面 ...
- xutils3文件上传、下载、get、post请求
@ContentView(R.layout.activity_xutils3_net) public class XUtils3NetActivity extends Activity { @View ...
- CSS选择器(一)
一.CSS 元素选择器 最常见的 CSS 选择器是元素选择器.换句话说,文档的元素就是最基本的选择器. 如果设置 HTML 的样式,选择器通常将是某个 HTML 元素,比如 p.h1.em.a,甚至可 ...
- Elasticsearch使用记录
Elasticsearch使用记录 Elasticsearch的搭建方法 1.RPM方式搭建 首先去官网[https://www.elastic.co/downloads/elasticsearch# ...
- eclipse新建Maven项目
1.在eclipse中安装maven插件 2.点击File->new->maven project,出现弹窗后点击next. 接着在弹窗Select an Archetype中,filte ...
- H5 input默认数字键盘,显示为密码格式
<P> <span class="yzname w25">银行密码</span> <input class="j_passwor ...