随便选一个点当做根,跑每个点的深度(为了求LCA)d [ u ] ,和到根节点的距离(为了更新答案) l [ u ]

我们发现,由关键点和他们的LCA构成的虚树(其实就是忽略其他节点),由于还要回到原点,所以相当于是树的所有边权的2倍

怎么求?对于每一次标记,将所有的标记了的点按时间戳排序,那么答案就是一、二两点之间的距离,二、三点之间距离。。。。最后一个点和第一个点之间的距离的总和;

而两点之间的距离等于 l [ u ] + l [ v ] - 2 * l [ lca ( u , v ) ]

维护这些点时可以用set

#include<cstdio>
#include<iostream>
#include<set>
#include<cmath>
#define getchar() *S++
#define ll long long
#define R register int
const int N=100010,Inf=0x3f3f3f3f;
char RR[100000005],*S=RR;
using namespace std;
inline int g() {R ret=0; register char ch; while(!isdigit(ch=getchar())); do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret;
}
int n,m,num,cnt;
int vr[N<<1],nxt[N<<1],w[N<<1],fir[N],dfn[N],rw[N],d[N],f[N][18];
set<int>s;
set<int>::iterator it;
ll ans,l[N];
bool vis[N];
inline void add(int u,int v,int ww) {vr[++cnt]=v,w[cnt]=ww,nxt[cnt]=fir[u],fir[u]=cnt;}
void dfs(int u) { dfn[u]=++num,rw[num]=u;for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];if(d[v]) continue; d[v]=d[u]+1; l[v]=l[u]+w[i]; f[v][0]=u; R p=u;for(R j=0;f[p][j];++j) f[v][j+1]=f[p][j],p=f[p][j];dfs(v);}
}
inline int lca(int u,int v) {if(d[u]<d[v]) swap(u,v); R lim=log2(d[u])+1;for(R j=lim;j>=0;--j) if(d[f[u][j]]>=d[v]) u=f[u][j];if(u==v) return u;for(R j=lim;j>=0;--j) if(f[u][j]!=f[v][j]) u=f[u][j],v=f[v][j];return f[u][0];
}
inline ll dis(int u,int v) {return l[u]+l[v]-2*l[lca(u,v)];}
signed main() {fread(RR,sizeof(RR),1,stdin);n=g(),m=g();for(R i=1,u,v,w;i<n;++i) u=g(),v=g(),w=g(),add(u,v,w),add(v,u,w);d[1]=1;dfs(1); s.insert(-Inf),s.insert(Inf);for(R i=1,x;i<=m;++i) { x=g(); register long long flg; if(vis[x]) s.erase(dfn[x]),flg=-1; else s.insert(dfn[x]),flg=1; vis[x]^=1;it=s.upper_bound(dfn[x]); R r=*it,l=*(--it); if(l>=dfn[x]) l=*(--it);//cout<<l<<" "<<dfn[x]<<" "<<r<<endl;if(l!=-Inf) ans+=flg*dis(rw[l],x); if(r!=Inf) ans+=flg*dis(x,rw[r]);if(l!=-Inf&&r!=Inf) ans-=flg*dis(rw[l],rw[r]); register long long tmp=(s.size()>3)?dis(rw[*++s.begin()],rw[*--(--s.end())]):0;printf("%lld\n",ans+tmp);}
}


2019.04.18

转载于:https://www.cnblogs.com/Jackpei/p/10732622.html

BZOJ 3991: [SDOI2015]寻宝游戏相关推荐

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

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

  2. SDOI2015寻宝游戏 dfs序+set

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

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

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

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

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

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

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

  6. bzoj 5285: [Hnoi2018]寻宝游戏

    Description Solution 把输入的 \(n\) 个二进制数看作一个大小为 \(n*m\) 的矩阵 把每一列压成一个二进制数,其中最高位是最下面的元素 然后就有了 \(m\) 个二进制数 ...

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

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

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

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

  9. hdu 6289 寻宝游戏

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

最新文章

  1. thrift使用小记_CUDev-ChinaUnix博客
  2. 八条是阿里6万工程师正在重点攻克的难关
  3. Kotlin的基本数值类型问题:是对象?还是基本数据类型?
  4. 干货!表达式树解析框架(3)
  5. 变异蛮牛 树,dfs,二分图染色 牛客白月赛44
  6. [jzoj NOIP2018模拟 11.01]
  7. Windows下CodeBlocks安装及配置注意事项
  8. mysql5.6-5.7性能调优
  9. linux mysql web界面吗_Linux下安装MySQL Web 管理工具phpMyAdmin
  10. POJ - 3190
  11. 判断一个整数是不是回文
  12. html 颜色在线取色器
  13. 全概率公式和贝叶斯公式(转载)
  14. ASO优化选词:三种方法教你精准定位关键词
  15. 利用tushare数据计算期货主力合约的活跃度
  16. IQ使命 Marrakech 马拉喀什(六边形图案)攻略
  17. 电商平台--Mysql主从搭建(2)
  18. 华东交通大学计算机调剂,【通知】华东交通大学2020年硕士研究生调剂通知
  19. ANSYS CFX19.0中的SA模型设置
  20. Elastix 设置呼叫转移

热门文章

  1. PAI平台搭建企业级个性化推荐系统
  2. 从零点五开始用Unity做半个2D战棋小游戏(三)
  3. 视觉、概念、故事——角色设计三原色
  4. 安卓App热补丁动态修复技术:让App像Web一样发布新版本
  5. eclipse是否免费
  6. SQL基础【十五、join、Inner join、Left join、Right join、Full join】
  7. Oracle 中文分词CHINESE_VGRAM_LEXER与CHINESE_LEXER比较
  8. 让CMD窗口显示中文[JAVAC输出中文错误信息乱码的解决]
  9. RAC Failover三种方式
  10. 什么叫优雅降级和渐进增强