传送门:>Here<

题意:给出一棵树(有边权),刚开始键值全部为0。每次对其中一个键值进行异或,问每一次修改之后:选择任意一个点出发走到所有为1的点再走回来的最短路

解题思路

由于N,M都是十万级别的,所以必须在线处理。很容易想到每次只需要对答案做出一点修改即可

考虑现在有$k$的节点有宝藏,那么假设他们共同在某一棵子树内,那么整棵树的其他部分根本不需要遍历到。因此我们需要找到这个子树的根,这个根就是目前所有节点的LCA。然后考虑从这个LCA出发开始走,总是会先走到DFS序较小的这样最优——因为DFS序比当前节点大只有两种情况:1.在当前节点的子树内 2.在当前节点的上面。对于第一种情况,显然可以免去走很多路,而对于第二种情况是无法避免的。

因此我们可以维护一个set,里面的元素是所有为1的点,并且按照DFS序从小到大排。为了让总路程最短,也就是让任意两个相邻的DFS序的元素之间的路程最短。因此我们的答案就是$Dis(set[1],set[2]) + Dis(set[2],set[3]) + ... + Dis(set[k-1],set[k]) + Dis(set[k],set[1])$。每一次插入一个元素,删除其相邻两点之间的$。事实上,由于从哪里出发要回到哪里,因此整个路径会形成一个环,所以从环上的任意一个点出发都是不会影响的。

每一次插入一个元素,删除其相邻两点之间的$Dis$,并且连接当前节点和相邻两个节点。删除同理。在set中可以采用lowerbound或者find函数。注意要特判边界情况

Code

如果lowerbound找到了end,意味着当前这个DFS是最大的,因此相邻的应该找打begin。找到start同理(昨天调试了两个小时……)

/*By DennyQi 2018.8.11*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#include <set>
#define r read()
#define Max(a,b) (((a)>(b)) ? (a) : (b))
#define Min(a,b) (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
const int MAXN = ;
const int MAXM = ;
const int INF = ;
inline int read(){
int x = ; int w = ; register int c = getchar();
while(c ^ '-' && (c < '' || c > '')) c = getchar();
if(c == '-') w = -, c = getchar();
while(c >= '' && c <= '') x = (x << ) + (x << ) + c - '', c = getchar(); return x * w;
}
struct BaoZang{
int d,i;
};
bool operator < (const BaoZang& a, const BaoZang& b){
return a.d < b.d;
}
int N,M,x,y,ans,dfs_clock,w;
int first[MAXN<<],nxt[MAXN<<],to[MAXN<<],cost[MAXN<<],num_edge;
int dfn[MAXN],dep[MAXN],dis[MAXN],f[MAXN][],val[MAXN];
set <BaoZang> qxz;
inline void add(int u, int v, int w){
to[++num_edge] = v;
cost[num_edge] = w;
nxt[num_edge] = first[u];
first[u] = num_edge;
}
void DFS(int u, int _f, int d){
dfn[u] = ++dfs_clock;
dep[u] = d;
f[u][] = _f;
for(int i = ; (<<i) <= dep[u]; ++i){
f[u][i] = f[f[u][i-]][i-];
}
int v;
for(int i = first[u]; i; i = nxt[i]){
if((v = to[i]) == _f) continue;
dis[v] = dis[u] + cost[i];
DFS(v, u, d+);
}
}
inline int LCA(int a, int b){
if(dep[a] < dep[b]) swap(a, b);
for(int i = ; i >= ; --i){
if(dep[a] - (<<i) < dep[b]) continue;
a = f[a][i];
}
if(a == b) return a;
for(int i = ; i >= ; --i){
if(f[a][i] == f[b][i]) continue;
a = f[a][i], b = f[b][i];
}
return f[a][];
}
int main(){
// freopen(".in","r",stdin);
N = r, M = r;
for(int i = ; i < N; ++i){
x = r, y = r, w = r;
add(x, y, w);
add(y, x, w);
}
DFS(, , );
while(M--){
x = r;
if(qxz.size() == ){
val[x] = ;
qxz.insert((BaoZang){dfn[x],x});
printf("0\n");
continue;
}
if(!val[x]){
val[x] = ;
set<BaoZang>::iterator it = qxz.lower_bound((BaoZang){dfn[x], x});
if(it == qxz.end()){
it = qxz.begin();
}
set<BaoZang>::iterator it2;
if(it2 == qxz.begin()){
it2 = qxz.end();
--it;
}
else{
it2 = --it; ++it;
}
ans -= dis[it->i] + dis[it2->i] - * dis[LCA(it->i, it2->i)];
ans += dis[it->i] + dis[x] - * dis[LCA(it->i, x)];
ans += dis[x] + dis[it2->i] - * dis[LCA(x, it2->i)];
qxz.insert((BaoZang){dfn[x], x});
}
else{
val[x] = ;
set<BaoZang>::iterator it = qxz.find((BaoZang){dfn[x], x});
set<BaoZang>::iterator it1,it2;
if(it == qxz.begin()){
it1 = --qxz.end();
it2 = ++it; --it;
}
else if(it == --qxz.end()){
it1 = --it; ++it;
it2 = qxz.begin();
}
else{
it1 = --it; ++it;
it2 = ++it; --it;
}
ans += dis[it->i] + dis[it2->i] - * dis[LCA(it->i, it2->i)];
ans -= dis[it->i] + dis[x] - * dis[LCA(it->i, x)];
ans -= dis[x] + dis[it2->i] - * dis[LCA(x, it2->i)];
qxz.erase((BaoZang){dfn[x], x});
}
printf("%d\n", ans);
}
return ;
}

[SDOI2015] 寻宝游戏的更多相关文章

  1. [BZOJ3991][SDOI2015]寻宝游戏

    [BZOJ3991][SDOI2015]寻宝游戏 试题描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择 ...

  2. bzoj 3991: [SDOI2015]寻宝游戏 虚树 set

    目录 题目链接 题解 代码 题目链接 bzoj 3991: [SDOI2015]寻宝游戏 题解 发现每次答案就是把虚树上的路径*2 接在同一关键点上的点的dfs序是相邻的 那么用set动态维护dfs序 ...

  3. P3320 [SDOI2015]寻宝游戏 解题报告

    P3320 [SDOI2015]寻宝游戏 题目描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有\(N\)个村庄和\(N-1\)条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以 ...

  4. 【LG3320】[SDOI2015]寻宝游戏

    [LG3320][SDOI2015]寻宝游戏 题面 洛谷 题解 不需要建虚树的虚树2333... 贪心地想一下,起始节点肯定是在关键点上,访问顺序就是\(dfs\)序. 那么对于每次询问, \[ An ...

  5. 3991: [SDOI2015]寻宝游戏

    3991: [SDOI2015]寻宝游戏 https://www.lydsy.com/JudgeOnline/problem.php?id=3991 分析: 虚树+set. 要求树上许多点之间的路径的 ...

  6. 【BZOJ3991】[SDOI2015]寻宝游戏 树链的并+set

    [BZOJ3991][SDOI2015]寻宝游戏 Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩 ...

  7. P3320 [SDOI2015]寻宝游戏

    题目 P3320 [SDOI2015]寻宝游戏 做法 很巧妙的一种思路,懂了之后觉得大水题 首先要知道:在一棵树上标记一些点,然后从任意一点出发,遍历所有的的最小路径为\(dfs\)序从小到大遍历 那 ...

  8. CH#56C 异象石 和 BZOJ3991 [SDOI2015]寻宝游戏

    异象石 CH Round #56 - 国庆节欢乐赛 描述 Adera是Microsoft应用商店中的一款解谜游戏. 异象石是进入Adera中异时空的引导物,在Adera的异时空中有一张地图.这张地图上 ...

  9. [SDOI2015]寻宝游戏(LCA,set)

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

  10. [bzoj3991][SDOI2015]寻宝游戏_树链的并_倍增lca_平衡树set

    寻宝游戏 bzoj-3991 SDOI-2015 题目大意:题目链接. 注释:略. 想法:我们发现如果给定了一些点有宝物的话那么答案就是树链的并. 树链的并的求法就是把所有点按照$dfs$序排序然后相 ...

随机推荐

  1. 朱晔的互联网架构实践心得S2E3:品味Kubernetes的设计理念

    Kubernetes(k8s)是一款开源的优秀的容器编排调度系统,其本身也是一款分布式应用程序.虽然本系列文章讨论的是互联网架构,但是k8s的一些设计理念非常值得深思和借鉴,本人并非运维专家,本文尝试 ...

  2. 初识Python-1

    1,计算机基础. 2,python历史. 宏观上:python2 与 python3 区别: python2 源码不标准,混乱,重复代码太多, python3 统一 标准,去除重复代码. 3,pyth ...

  3. getQueryStringByName url参数/

    MasterId: (masterIdUrl != null && masterIdUrl != "") ? masterIdUrl : null ClassId: ...

  4. 01-HTML介绍

    1.WEB标准 web准备介绍: w3c:万维网联盟组织,用来制定web标准的机构(组织) web标准:制作网页遵循的规范 web准备规范的分类:结构标准.表现标准.行为标准. 结构:html.表示: ...

  5. IP核引发的关于定,浮点数的认识

    上面是一段关于CORDIC_IP测试文件,用于计算给定角度的sin值和cos值,关于数值表示规则在此不再重复,仅仅说明以下3点: 1  数采用原码,反码,补码,本身并没有正确与否之分(这一点很重要,我 ...

  6. nginx的The page you are looking for is temporarily unavailable错误解决办法

    访问网站时出现如下错误,如下图: 检查php fastcgi进程数,如下图: 输出0则表示fastcgi进程数够大,修改scgi_params文件,如下图: 然后重启php-fpm和nginx,重新访 ...

  7. Magic Stones CodeForces - 1110E (思维+差分)

    E. Magic Stones time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  8. 牛客练习赛 A题 筱玛的快乐

    链接:https://ac.nowcoder.com/acm/contest/342/A来源:牛客网 筱玛的快乐 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语 ...

  9. Windows之文件夹中打开PowerShell

    Windows之文件夹中打开PowerShell 为了解决Windows中在某个路径下使用PowerShell,而不是使用传统的cd命令切换过去,具体做法如下: 方法一 打开文件夹 在文件夹的内容区按 ...

  10. CRM系统(第一部分)

      阅读目录 1.需求分析 2.数据库表设计 3.起步 4.录入数据 5.知识点 1.需求分析 CRM客户关系管理软件---> 学员管理 用户:企业内部用户 用户量: 业务场景: 2.数据库表设 ...