P3320 [SDOI2015]寻宝游戏
若当前点集S, s[i]的dfn为a[i], 且a单调.
则答案即:d(a[1], a[2]) + d(a[2], a[3]) +… + d(a[n - 1], a[n]) + d(a[n], a[1]).
set维护.(set用法见蓝书.)
代码1如下:

#include <cstdio>
#include <cctype>
#include <algorithm>
#include <cmath>
#include <set>using namespace std; #define ll long longinline int read() {int x = 0, f = 0; char ch = getchar(); while (!isdigit(ch)) f = ch == '-', ch = getchar(); while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar(); return f ? -x : x;
}inline void print(ll x) {if (x < 0) x = -x; if (x < 10) putchar(x + '0'); else {print(x / 10); putchar(x % 10 + '0'); }
}const int N = 1e5 + 5;
int n, m;
int head[N], nex[N << 1], ver[N << 1], val[N << 1], tot;
int dfn[N], idx[N], num;
int fa[N][20], dep[N];
int vis[N];
set<int> s;
ll dist[N], ans; void Addedge(int x, int y, int z) {ver[++tot] = y; val[tot] = z; nex[tot] = head[x]; head[x] = tot;
}void dfs(int x, int fat) {dfn[x] = ++num; idx[num] = x; fa[x][0] = fat; dep[x] = dep[fat] + 1; for (int i = 1; i < 20; ++i) {fa[x][i] = fa[fa[x][i - 1]][i - 1]; }for (int i = head[x]; i; i = nex[i]) {int y = ver[i], z = val[i]; if (y == fat) continue; dist[y] = dist[x] + 1ll * z; dfs(y, x); }
}int lca(int x, int y) {if (dep[x] > dep[y]) swap(x, y); while (dep[x] < dep[y]) y = fa[y][(int)log2(dep[y] - dep[x])]; if (x == y) return x; for (int i = 19; i >= 0; --i) {if (fa[x][i] != fa[y][i]) {x = fa[x][i]; y = fa[y][i]; }}return fa[x][0];
}ll Getd(int x, int y) {int f = lca(x, y); return dist[x] + dist[y] - (dist[f] << 1);
}int main() {n = read(); m = read(); for (int i = 1; i < n; ++i) {int uu = read(), vv = read(), ww = read(); Addedge(uu, vv, ww); Addedge(vv, uu, ww); }dfs(1, 0); while (m--) {int t = read(), x = dfn[t]; set<int>::iterator i = s.find(x), pre, nxt; if (i == s.end()) {  s.insert(x); i = s.find(x); if (i == s.begin()) pre = --s.end(); else pre = --i, ++i;if (i == --s.end()) nxt = s.begin(); else nxt = ++i, --i; ans += Getd(idx[*i], idx[*pre]) + Getd(idx[*i], idx[*nxt]) - Getd(idx[*pre], idx[*nxt]); } else {i = s.find(x); if (i == s.begin()) pre = --s.end(); else pre = --i, ++i;if (i == --s.end()) nxt = s.begin(); else nxt = ++i, --i; ans -= Getd(idx[*i], idx[*pre]) + Getd(idx[*i], idx[*nxt]) - Getd(idx[*pre], idx[*nxt]); s.erase(i); }print(ans); putchar('\n'); }return 0;
}

代码2如下:

#include <cstdio>
#include <cctype>
#include <algorithm>
#include <cmath>
#include <set>using namespace std; #define ll long longinline int read() {int x = 0, f = 0; char ch = getchar(); while (!isdigit(ch)) f = ch == '-', ch = getchar(); while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar(); return f ? -x : x;
}inline void print(ll x) {if (x < 0) x = -x; if (x < 10) putchar(x + '0'); else {print(x / 10); putchar(x % 10 + '0'); }
}const int N = 1e5 + 5;
int n, m;
int head[N], nex[N << 1], ver[N << 1], val[N << 1], tot;
int dfn[N], idf[N], num;
int fa[N][20], dep[N];
set<int> s;
set<int>::iterator it;
ll dist[N], ans;
int vis[N]; void Addedge(int x, int y, int z) {ver[++tot] = y; val[tot] = z; nex[tot] = head[x]; head[x] = tot;
}void dfs(int x, int fat) {dfn[x] = ++num; idf[num] = x; fa[x][0] = fat; dep[x] = dep[fat] + 1; for (int i = 1; i < 20; ++i) {fa[x][i] = fa[fa[x][i - 1]][i - 1]; }for (int i = head[x]; i; i = nex[i]) {int y = ver[i], z = val[i]; if (y == fat) continue; dist[y] = dist[x] + 1ll * z; dfs(y, x); }
}int lca(int x, int y) {if (dep[x] > dep[y]) swap(x, y); while (dep[x] < dep[y]) y = fa[y][(int)log2(dep[y] - dep[x])]; if (x == y) return x; for (int i = 19; i >= 0; --i) {if (fa[x][i] != fa[y][i]) {x = fa[x][i]; y = fa[y][i]; }}return fa[x][0];
}ll Getd(int x, int y) {int f = lca(x, y); return dist[x] + dist[y] - (dist[f] << 1);
}int main() {n = read(); m = read(); for (int i = 1; i < n; ++i) {int uu = read(), vv = read(), ww = read(); Addedge(uu, vv, ww); Addedge(vv, uu, ww); }dfs(1, 0); while (m--) {int t = read(), x = dfn[t]; if (!vis[t]) {vis[t] = 1; s.insert(x); int pre = idf[(it = s.lower_bound(x)) == s.begin() ? *--s.end() : *--it], nxt = idf[(it = s.lower_bound(x)) == --s.end() ? *s.begin() : *++it];ans += Getd(t, pre) + Getd(t, nxt) - Getd(pre, nxt); } else {vis[t] = 0;int pre = idf[(it = s.lower_bound(x)) == s.begin() ? *--s.end() : *--it], nxt = idf[(it = s.lower_bound(x)) == --s.end() ? *s.begin() : *++it];ans -= Getd(t, pre) + Getd(t, nxt) - Getd(pre, nxt);  s.erase(x); }print(ans); putchar('\n'); }return 0;
}

经实测,代码2优于代码1.
迭代器:
set<int>::iterator it;
++it; --it; it++; it--;
s.begin() --s.end() O(1)
s.insert(x); s.erase(x); s.find(x); //s.find(x)不存在x返回x.end()
s.lower_bound(x) s.upper_bound(x) // >= >

P3320 [SDOI2015]寻宝游戏相关推荐

  1. SDOI2015寻宝游戏 dfs序+set

    SDOI2015寻宝游戏 好像是一道虚树入门题? 虚树???不会不会我弱死了.. Solution: 关键点间的最小路径,就是在保证尽量少走重复路的前提下走出来的一条经过所有关键点的路径. 基于这个思 ...

  2. 【BZOJ 3991】 [SDOI2015]寻宝游戏

    3991: [SDOI2015]寻宝游戏 Time Limit: 40 Sec Memory Limit: 128 MB Submit: 251 Solved: 137 [Submit][Status ...

  3. 洛谷 P3320: bzoj 3991: LOJ 2182: [SDOI2015]寻宝游戏

    题目传送门:LOJ #2182. 题意简述: 一棵 \(n\) 个节点的树,边有边权. 每个点可能是关键点,每次操作改变一个点是否是关键点. 求所有关键点形成的极小联通子树的边权和的两倍. 题解: 有 ...

  4. BZOJ 3991: [SDOI2015]寻宝游戏

    随便选一个点当做根,跑每个点的深度(为了求LCA)d [ u ] ,和到根节点的距离(为了更新答案) l [ u ] 我们发现,由关键点和他们的LCA构成的虚树(其实就是忽略其他节点),由于还要回到原 ...

  5. 洛谷3320 SDOI2015寻宝游戏(set+dfs序)(反向迭代器的注意事项!)

    被\(STL\)坑害了一个晚上,真的菜的没救了啊. 准确的说是一个叫\(reverse\ iterator\)的东西,就是我们经常用的\(rbegin()\) 有一个非常重要的性质 在反向迭代器中,+ ...

  6. P3320:寻宝游戏(生成树)

    解析 大结论题- 实在是不知道这题和虚树有半毛钱关系吗- 引理 给出一个按照dfs排列的点集S={a1,a2-ak} 它们的极小联通子树的边权和的二倍等于∑dis(a1,a2)+dis(a2,a3)+ ...

  7. 【bzoj3991】[SDOI2015]寻宝游戏 树链的并+STL-set

    题目描述 给出一棵树,初始每个点都是非必经的.多次改变某个点的必经状态,并询问从任意一个点出发,经过所有必经的点并回到该点的最小路程. 输入 第一行,两个整数N.M,其中M为宝物的变动次数. 接下来的 ...

  8. 【SDOI2015】【BZOJ3991】寻宝游戏

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

  9. 河北工业大学c语言寻宝游戏,计算机技术基础(c语言)课程设计寻宝游戏.doc

    计算机技术基础(c语言)课程设计寻宝游戏 计算机技术基础(c语言)课程设计 寻宝游戏 #include #include #include #include #include #define ESC ...

  10. hdu 6289 寻宝游戏

    寻宝游戏 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Sub ...

最新文章

  1. [裴礼文数学分析中的典型问题与方法习题参考解答]5.1.21
  2. 监控利器之 Prometheus
  3. RocketMQ Apache顶级项目之路
  4. Window平台 mysql8.0下载安装方式
  5. 总结:Sharepoint2010 Client Object Model -- Silverlight Client
  6. matlab绘图z=sin(x,用matlab编写函数文件,实现绘制函数 z= sin(x+y)/(x+y)在【-2:2,-2:2]的图像...
  7. 删除排序链表中的重复元素Python解法
  8. jq分页 不刷新页面_jQuery无刷新分页完整实例代码
  9. 揭秘 | 小米最新款12PRO智能动态刷新率技术原理
  10. 数论 —— 高次同余方程与 BSGS 算法
  11. 剑指offer——11.旋转数组的最小数字
  12. 【信号处理第十二章】转置卷积
  13. IoTDB MPP框架源码解读之SQL的一生(襁褓)
  14. NPOI实现Word表格新增一行
  15. windows 技术篇-局域网文件传输效率优化实例演示,下载共享地址里的文件慢解决方法
  16. Hair-Gan论文翻译
  17. LeetCode 28 Implement strStr()(实现strStr()函数)
  18. 【板绘手绘线稿素材资料】从素描到板绘,超全的人物嘴巴画法!
  19. Macbook上打开多个终端的方法
  20. 松散架构(Loosely Coupled Architecture)

热门文章

  1. 思科三层交换机不同vlan互通_Cisco三层交换机实现不同vlan之间的通信
  2. python 时间模块判断上午还是下午_Python的时间模块小结(转自:不懂真人)
  3. 使用BOOTICE 恢复系统启动项
  4. 上海好吃加好玩-详细分类版
  5. datetime instant 转_java8 Instant 时间及转换操作
  6. vs2013断点调试
  7. 艾可森 mysql,国足进世界杯有戏!巴西归化球员表决心:中国对我好,我必须努力...
  8. 程序员必须了解的10大技术搜索引擎
  9. 电脑重装系统后文件怎么恢复
  10. Kaldi:提特征报错“compute-fbank-feats: error while loading shared libraries: libkaldi-hmm.so”