LOJ10132
在 Adera 的异时空中有一张地图。这张地图上有 N 个点,有 N-1 条双向边把它们连通起来。起初地图上没有任何异象石,在接下来的 M 个时刻中,每个时刻会发生以下三种类型的事件之一:
- 地图的某个点上出现了异象石(已经出现的不会再次出现);
- 地图某个点上的异象石被摧毁(不会摧毁没有异象石的点);
- 向玩家询问使所有异象石所在的点连通的边集的总长度最小是多少。
请你作为玩家回答这些问题。下图是一个例子,灰色节点表示出现了异象石,加粗的边表示被选为连通异象石的边集。

输入格式
第一行有一个整数 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 ≤ 10^3;
对于另 20% 的数据,地图是一条链,或者一朵菊花;
对于 100% 的数据,1≤ n,m ≤ 10^5,1 ≤ x,y ≤ n,x ̸= y,1 ≤ z ≤ 10^9。
________________________________________________________________________________________
有一个很有趣的结论,把所有的点连接起来的的最短距离刚好是,dfs序中所有选取点相邻两点之间的距离,所以用LCA就可以了。比较麻烦的是选取点的次序,不能暴力,太慢!所以想到了平衡树,太麻烦了。后来看书上说用SET。比赛时不知道会不会挂。
SET用的不熟练,很多是临时查的,所以调了半天!
________________________________________________________________________________________
1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const ll maxn=1e5+10;
5 struct edge
6 {
7 ll u,v,w,nxt;
8 }e[maxn<<1];
9 ll head[maxn],js;
10 ll n,m;
11 void addage(ll u,ll v,ll w)
12 {
13 e[++js].u=u;e[js].v=v;e[js].w=w;
14 e[js].nxt=head[u];head[u]=js;
15 }
16 ll cx[maxn],xh[maxn];
17 set <ll> s;
18 ll f[maxn][20],dep[maxn],deps[maxn];
19 void dfs(ll u,ll fa)
20 {
21 dep[u]=dep[fa]+1;
22 for(ll i=head[u];i;i=e[i].nxt)
23 {
24 ll v=e[i].v;
25 if(v!=fa)
26 {
27 f[v][0]=u;deps[v]=deps[u]+e[i].w;
28 for(int j=1;j<20;++j)
29 {
30 f[v][j]=f[f[v][j-1]][j-1];
31 }
32 dfs(v,u);
33 }
34 }
35 }
36 ll ind;
37 ll ans;
38 void dfsf(ll u,ll fa)
39 {
40 cx[++ind]=u;xh[u]=ind;
41 for(int i=head[u];i;i=e[i].nxt)
42 {
43 ll v=e[i].v;
44 if(v!=fa)dfsf(v,u);
45 }
46 }
47 ll lca(ll u,ll v)
48 {
49 if(dep[u]<dep[v])swap(u,v);
50 for(int i=19;i>=0;--i)if(dep[f[u][i]]>=dep[v])u=f[u][i];
51 if(u==v)return v;
52 for(int i=19;i>=0;--i)if(f[u][i]!=f[v][i])u=f[u][i],v=f[v][i];
53 return f[u][0];
54 }
55 ll lcaf(ll u,ll v)
56 {
57 ll l=lca(u,v);
58 return deps[u]+deps[v]-deps[l]-deps[l];
59 }
60 int main()
61 {
62 scanf("%lld",&n);
63 for(int i=1;i<n;++i)
64 {
65 ll u,v,w;
66 scanf("%lld%lld%lld",&u,&v,&w);
67 addage(u,v,w);addage(v,u,w);
68 }
69 dfs(1,0);
70 scanf("%lld",&m);
71 dfsf(1,0);
72 char ss[3];
73 int x;
74 pair<set<ll>::iterator,bool> pr;
75 set<ll>::iterator it,it2,tp;
76 while(m--)
77 {
78 scanf("%s",ss);
79 if(ss[0]=='+')
80 {
81 scanf("%d",&x);
82 if(s.size()==0)
83 {
84 s.insert(xh[x]);
85 continue;
86 }
87 it=s.lower_bound(xh[x]);it2=it;
88 if(it==s.end())it=s.begin();
89 if(it2==s.begin()){it2=s.end();it2--;}else it2--;
90 ans+=lcaf(cx[*it],x)+lcaf(x,cx[*it2])-lcaf(cx[*it],cx[*it2]);
91 s.insert(xh[x]);
92 }
93 else if(ss[0]=='-')
94 {
95 scanf("%d",&x);
96 tp=s.end();tp--;
97 it=s.lower_bound(xh[x]);it2=it;
98 if(it==tp)it=s.begin();else it++;
99 if(it2==s.begin())it2=tp;else it2--;
100 ans+=lcaf(cx[*it],cx[*it2])-lcaf(x,cx[*it])-lcaf(x,cx[*it2]);
101 s.erase(xh[x]);
102 }
103 else
104 {
105 printf("%lld\n",ans/2);
106 }
107 }
108 return 0;
109 }
LOJ10132的更多相关文章
随机推荐
- ExecutionListener,TaskListener流程监听 和任务监听
1.ExecutionListener 流程实例的启动和结束. 选中一条连线. 节点的开始和结束. 网关的开始和结束. 中间事件的开始和结束. 开始时间结束或结束事件开始. 2.TaskListene ...
- Hive基于UDF进行文本分词
本文大纲 UDF 简介 Hive作为一个sql查询引擎,自带了一些基本的函数,比如count(计数),sum(求和),有时候这些基本函数满足不了我们的需求,这时候就要写hive hdf(user de ...
- JDBC(六)—— 数据库事务
数据库事务 事务 一组逻辑操作单元,使数据从一种状态变换到另一种状态 事务处理 保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式. 当在一个事务中执行多个操作时,要么所有事 ...
- JavaWeb代码复用
servlet部分,可能用得到的复用的代码: 1.dopost设置字符 request.setCharacterEncoding("utf-8"); response.setCha ...
- 线程上下文类加载器(Context ClassLoader)
1.线程上下文类加载器是从jdk1.2开始引入的,类Thread中的getContextClassLoader()与setContextClassLoader(ClassLoader c1),分别用来 ...
- cmake - 编译
cmake在编译期间会使用到的命令总结: 1.指定编译器并同时设置编译选项 set(CMAKE_CXX_COMPILER "clang++" ) # 显示指定使用的C++编译器 s ...
- Linux下nginx反向代理负载均衡几种方式以及配置
下面以ip地址192.168.1.1 和192.168.1.2举例 1.轮询 (1).轮询:每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除. upstream ...
- Dubbo 就是靠它崭露头角!(身为开源框架很重要的一点)
Hola,我是 yes. 经过了 RPC 核心和 Dubbo 微内核两篇文章后,今天终于要稍稍深入一波 Dubbo 了. 作为一个通用的 RPC 框架,性能是很重要的一环,而易用性和扩展性也极为重要. ...
- Linux常用命令(df&dh)
在Linux下查看磁盘空间使用情况,最常使用的就是du和df了.然而两者还是有很大区别的,有时候其输出结果甚至非常悬殊. du的工作原理 du命令会对待统计文件逐个调用fstat这个系统调用,获取文件 ...
- 实现Vue的多页签组件
在之前的博客中 关于vue的多页面标签功能,对于嵌套router-view缓存的最终无奈解决方法 有写过vue的多页签功能的解决方案 可以看到我当时那个多页签的组件还是比较简单 的,只有打开跟关闭 ...