题解

终于了解怎么动态维护虚树了

就是把点按照dfs序排个序啊

这道题显然是求虚树上所有边长的两倍

我们把dfs序排完序,相邻两个点加上路径长(包括首尾),删除的时候删一个点减去它到两边再加上新近相邻的两个点即可

增加同理

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define space putchar(' ')
#define enter putchar('\n')
#define mp make_pair
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
} int N,M;
struct node {
int to,next;int64 val;
}E[MAXN * 2];
int head[MAXN],sumE,st[MAXN * 2][20],len[MAXN * 2],pos[MAXN],dep[MAXN],dfn[MAXN],idx,tot;
int pre[MAXN],suf[MAXN];
int64 dis[MAXN];
bool vis[MAXN];
struct cmp {
bool operator () (const int &a,const int &b) const {
return dfn[a] < dfn[b];
}
};
set<int,cmp> S;
void add(int u,int v,int64 c) {
E[++sumE].to = v;
E[sumE].next = head[u];
E[sumE].val = c;
head[u] = sumE;
}
int min_dep(int a,int b) {
return dep[a] < dep[b] ? a : b;
}
int lca(int a,int b) {
a = pos[a];b = pos[b];
if(a > b) swap(a,b);
int l = len[b - a + 1];
return min_dep(st[a][l],st[b - (1 << l) + 1][l]);
}
int64 dist(int a,int b) {
return dis[a] + dis[b] - 2 * dis[lca(a,b)];
}
void dfs(int u,int fa) {
dfn[u] = ++idx;
st[++tot][0] = u;
dep[u] = dep[fa] + 1;
pos[u] = tot;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa) {
dis[v] = dis[u] + E[i].val;
dfs(v,u);
st[++tot][0] = u;
}
}
}
void Init() {
read(N);read(M);
int u,v;int64 c;
for(int i = 1 ; i < N ; ++i) {
read(u);read(v);read(c);
add(u,v,c);add(v,u,c);
}
dfs(1,0);
for(int j = 1 ; j <= 19 ; ++j) {
for(int i = 1 ; i <= tot ; ++i) {
if(i + (1 << j) - 1 > tot) break;
st[i][j] = min_dep(st[i][j - 1],st[i + (1 << j - 1)][j - 1]);
}
}
for(int i = 2 ; i <= tot ; ++i) len[i] = len[i / 2] + 1;
}
void Solve() {
int t;
int64 ans = 0;
while(M--) {
read(t);
if(vis[t]) {
vis[t] = 0;
S.erase(t);
ans -= dist(t,pre[t]) + dist(t,suf[t]);
ans += dist(pre[t],suf[t]);
suf[pre[t]] = suf[t];
pre[suf[t]] = pre[t];
}
else {
vis[t] = 1;
S.insert(t);
auto k = S.find(t);
if(k == S.begin()) {
pre[t] = *(--S.end());
}
else {--k;pre[t] = *k;}
k = S.find(t);++k;
if(k == S.end()) {
suf[t] = *(S.begin());
}
else {suf[t] = *k;}
ans -= dist(pre[t],suf[t]);
ans += dist(t,pre[t]) + dist(t,suf[t]);
suf[pre[t]] = t;
pre[suf[t]] = t;
}
out(ans);enter;
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
}

【LOJ】#2182. 「SDOI2015」寻宝游戏的更多相关文章

  1. loj2182 「SDOI2015」寻宝游戏

    参考这里 #include <iostream> #include <cstdio> #include <set> using namespace std; typ ...

  2. 「SDOI2015」寻宝游戏

    传送门 Luogu 解题思路 发现一个性质: 对于所有的宝藏点 \({a_1,a_2...a_k}\) ,按照dfs序递增排列,答案就是: \(dis(a_1, a_2) + dis(a_2, a_3 ...

  3. LOJ #2183「SDOI2015」序列统计

    有好多好玩的知识点 LOJ 题意:在集合中选$ n$个元素(可重复选)使得乘积模$ m$为$ x$,求方案数对$ 1004535809$取模 $ n<=10^9,m<=8000且是质数,集 ...

  4. @loj - 2004@ 「SDOI2017」硬币游戏

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数 ...

  5. Loj #2494. 「AHOI / HNOI2018」寻宝游戏

    Loj #2494. 「AHOI / HNOI2018」寻宝游戏 题目描述 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得 ...

  6. LOJ #6436. 「PKUSC2018」神仙的游戏(字符串+NTT)

    题面 LOJ #6436. 「PKUSC2018」神仙的游戏 题解 参考 yyb 的口中的长郡最强选手 租酥雨大佬的博客 ... 一开始以为 通配符匹配 就是类似于 BZOJ 4259: 残缺的字符串 ...

  7. Loj #3056. 「HNOI2019」多边形

    Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...

  8. Loj #3044. 「ZJOI2019」Minimax 搜索

    Loj #3044. 「ZJOI2019」Minimax 搜索 题目描述 九条可怜是一个喜欢玩游戏的女孩子.为了增强自己的游戏水平,她想要用理论的武器武装自己.这道题和著名的 Minimax 搜索有关 ...

  9. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

随机推荐

  1. 开发Spring Shell应用程序

    2 开发Spring Shell应用程序 向shell提供命令非常简单,需要学习的注解很少.该命令的实现风格与使用依赖注入的应用程序的开发类相同,您可以利用Spring容器的所有特性来实现您的命令类. ...

  2. 【刷题】BZOJ 3495 PA2010 Riddle

    Description 有n个城镇被分成了k个郡,有m条连接城镇的无向边. 要求给每个郡选择一个城镇作为首都,满足每条边至少有一个端点是首都. Input 第一行有三个整数,城镇数n(1<=n& ...

  3. HGOI 20181030晚 题解

    Problem:给出全班人的个数总分和小明的分数(满分100分),求小明最低排名和最高排名 sol:假设小明的排名为k,总分为sum,小明的分数是r, 贪心求解, 最坏情况下,小明前面的比小明高一分( ...

  4. 普通平衡树Treap(含旋转)学习笔记

    浅谈普通平衡树Treap 平衡树,Treap=Tree+heap这是一个很形象的东西 我们要维护一棵树,它满足堆的性质和二叉查找树的性质(BST),这样的二叉树我们叫做平衡树 并且平衡树它的结构是接近 ...

  5. CentOS服务器配置SSH免密码登录

    由于工作需要,经常要登录到多台服务器远程操作,每次都是ssh user@host:port 再输入密码,时间长了,难免觉得乏味-- 故而从度娘那里扒来了一些让SSH免密码登录的办法,其实这也是使用Gi ...

  6. POJ 2135 Farm Tour (网络流,最小费用最大流)

    POJ 2135 Farm Tour (网络流,最小费用最大流) Description When FJ's friends visit him on the farm, he likes to sh ...

  7. String.format VS. StrSubstitutor VS. NamedParameterJdbcTemplate

    在Java中,想要用一个字符串模块根据参数的不同来产生不同的字符串,主要有以下两种办法: Java String.format() 在JDK1.5中,String类新增了一个很有用的静态方法Strin ...

  8. P3959 宝藏

    P3959 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 nn 个深埋在地下的宝藏屋, 也给出了这 nn 个宝藏屋之间可供开发的 mm 条道路和它们的长度. 小明决心亲自前往挖掘 ...

  9. 解决linux mysql命令 bash: mysql: command not found 的方法

    错误: root@DB-02 ~]# mysql -u root-bash: mysql: command not found 原因:这是由于系统默认会查找/usr/bin下的命令,如果这个命令不在这 ...

  10. 流媒体技术学习笔记之(十)HLS协议直播延时优化(35s到10S)

    1.首先要了解HLS延时的机制,也就是为什么会延时,延时主要发生在什么地方. HTTP Live Streaming 并不是一个真正实时的流媒体系统,这是因为对应于媒体分段的大小和持续时间有一定潜在的 ...