在 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 ≤ 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的更多相关文章

随机推荐

  1. [leetcode349]Intersection of Two Arrays

    设计的很烂的一道题 List<Integer> res = new ArrayList<>(); // int l1 = nums1.length; // int l2 = n ...

  2. JavaDailyReports10_18

    学习内容:HTML基本知识 1.通常标记具有默认属性,当一个标记中只有标记名时,使用默认属性. 2.HTML标记有两种:单标记和双标记,单标记的语法格式:  <标记名称/> 3.不同的属性 ...

  3. 30天自制OS(linux环境)-day1

    30天自制OS(linux环境)--第一天 我是在CentOS的环境上面实现的,使用ubuntu的环境也是类似的 第一步:因为要对二进制文件进行编辑,所以安装二进制编辑器hexedit(当然其他的也可 ...

  4. Linux下nginx反向代理负载均衡几种方式以及配置

    下面以ip地址192.168.1.1 和192.168.1.2举例 1.轮询   (1).轮询:每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除.  upstream ...

  5. HarmonyOS(LiteOs_m) 官方例程移植到STM32初体验

    HarmonyOS(LiteOs_m) 官方例程移植到STM32初体验 硬件平台 基于正点原子战舰V3开发板 MCU:STM32F103ZET6 片上SRAM大小:64KBytes 片上FLASH大小 ...

  6. DEDECMS自动编号(序号)autoindex属性(转)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 让织梦dedecms autoindex,itemindex 从0到1开始的办法! 1 2 3 [field:global name=autoin ...

  7. Solon rpc 之 SocketD 协议 - 消息订阅模式

    Solon rpc 之 SocketD 协议系列 Solon rpc 之 SocketD 协议 - 概述 Solon rpc 之 SocketD 协议 - 消息上报模式 Solon rpc 之 Soc ...

  8. Viser报错:dodge is not support linear attribute, please use category attribute!

    遇到这样的问题是因为x轴数据不能为为连续性的日期(日期格式为:YYYY-MM-DD),需要设置为分类属性(cat),有一些可能设置为timeCat,看具体情况 scale 参数支持以下类型 • ide ...

  9. Linux下的strip命令学习

    strip strip是Linux下的一个命令.可以用于给应用脱衣服,帮助我们抹除一些调试信息.(虽然不知道具体是什么,但是会用就好了) 在嵌入式开发领域用到的应该比较多 首先,先写一个示例看看 // ...

  10. 机器学习算法-logistic回归算法

    Logistic回归算法调试 一.算法原理 Logistic回归算法是一种优化算法,主要用用于只有两种标签的分类问题.其原理为对一些数据点用一条直线去拟合,对数据集进行划分.从广义上来讲这也是一种多元 ...