#2135. 「ZJOI2015」幻想乡战略游戏

分析:

  动态点分治,求加权重心,带修改。

  考虑如果知道了一个点s,如何求答案,那么首先可以点分治的思想,求每个联通块内所有点到分治中心距离和,然后加上分治中心到s的距离。

  当然有一部分会算重,就是s在i中,以fa[i]为分治中心的时候,就会算重s到i的连通块的部分,于是在记录每个联通块到此分治中心在点分树上的父节点的距离和。

  那么随机从一个分治中心出发,每次遍历它周围的点,如果周围的点存在更优的情况,那么往这个方向走更优,所有就往这方向走,即到这个点所在连通块的分治中心位置。

代码:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<bitset>
#define fore(i, u, v) for (int i = head[u], v = e[i].to; i; i = e[i].nxt, v = e[i].to)
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
struct Edge { int to, nxt, w; } e[N << ];
int head[N], Log[N], pos[N], siz[N], fa[N], val[N];
bool vis[N];
int En, Index, Mn, Root, Now;
LL dep[N], f[N][], va[N], vb[N], sum[N]; inline void add_edge(int u,int v,int w) {
++En; e[En].to = v, e[En].w = w, e[En].nxt = head[u]; head[u] = En;
++En; e[En].to = u, e[En].w = w, e[En].nxt = head[v]; head[v] = En;
}
void predfs(int u,int fa) {
pos[u] = ++Index; f[Index][] = dep[u];
fore(i, u, v)
if (v != fa) dep[v] = dep[u] + e[i].w, predfs(v, u), f[++Index][] = dep[u];
}
void preinit() {
for (int i = ; i <= Index; ++i) Log[i] = Log[i >> ] + ;
for (int j = ; j <= Log[Index]; ++j)
for (int i = ; i + ( << j) - <= Index; ++i)
f[i][j] = min(f[i][j - ], f[i + ( << (j - ))][j - ]);
}
void getroot(int u,int fa,int Size) {
int mx = ; siz[u] = ;
fore(i, u, v)
if (!vis[v] && v != fa)
getroot(v, u, Size), siz[u] += siz[v], siz[v] > mx ? mx = siz[v] : mx;
mx = max(mx, Size - siz[u]);
if (mx < Mn) Mn = mx, Root = u;
}
void solve(int u) {
vis[u] = ;
fore(i, u, v) if (!vis[v]) Mn = 1e9, getroot(v, u, siz[v]), fa[Root] = u, val[i] = Root, solve(Root);
}
LL LCA(int x,int y) {
x = pos[x], y = pos[y];
if (x > y) swap(x, y);
int k = Log[y - x + ];
return min(f[x][k], f[y - ( << k) + ][k]);
}
LL getdis(int x,int y) { return dep[x] + dep[y] - * LCA(x, y); }
LL Calc(int x) {
LL ans = ;
for (int i = x; i; i = fa[i])
ans += va[i] + sum[i] * getdis(x, i);
for (int i = x; fa[i]; i = fa[i])
ans -= vb[i] + sum[i] * getdis(x, fa[i]);
return ans;
}
void update() {
int x = read(), y = read();
for (int i = x; i; i = fa[i])
va[i] += y * getdis(x, i), sum[i] += y;
for (int i = x; fa[i]; i = fa[i])
vb[i] += y * getdis(x, fa[i]);
}
void query() {
int x = Now, y; LL Mn, tmp;
while () {
Mn = Calc(x); y = x;
fore(i, x, v)
if (val[i] && (tmp = Calc(v)) < Mn) Mn = tmp, y = val[i];
if (y == x) break;
x = y;
}
cout << Mn << "\n";
}
int main() {
int n = read(), Q = read();
for (int u, v, w, i = ; i < n; ++i)
u = read(), v = read(), w = read(), add_edge(u, v, w);
predfs(, ); preinit();
Mn = 1e9, getroot(, , n); Now = Root;
solve(Root);
while (Q --) update(), query();
return ;
}

LOJ #2135. 「ZJOI2015」幻想乡战略游戏的更多相关文章

  1. LOJ #2135. 「ZJOI2015」幻想乡战略游戏(点分树)

    题意 给你一颗 \(n\) 个点的树,每个点的度数不超过 \(20\) ,有 \(q\) 次修改点权的操作. 需要动态维护带权重心,也就是找到一个点 \(v\) 使得 \(\displaystyle ...

  2. loj 2135 「ZJOI2015」幻想乡战略游戏 - 动态点分治

    题目传送门 传送门 题目大意 给定一棵树,初始点权都为0,要求支持: 修改点权 询问带权重心 询问带权重心就在点分树上跑一下就行了.(枚举跳哪个子树更优) 剩下都是基础点分治. 学了一下11-dime ...

  3. LOJ2135 「ZJOI2015」幻想乡战略游戏

    题意 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和 ...

  4. [ZJOI2015][bzoj3924] 幻想乡战略游戏 [动态点分治]

    唉:-(动态点分治的思想真是复杂...... 先码住,再做几道题再来填坑 PS:接下来的Code因为用了倍增lca所以TLE一部分,但是懒得改成RMQ了...... Code: #include< ...

  5. 洛谷 P3345 [ZJOI2015]幻想乡战略游戏 解题报告

    P3345 [ZJOI2015]幻想乡战略游戏 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做 ...

  6. [ZJOI2015]幻想乡战略游戏——动态点分治

    [ZJOI2015]幻想乡战略游戏 带修改下,边点都带权的重心 随着变动的过程中,一些子树内的点经过会经过一些公共边.考虑能不能对这样的子树一起统计. 把树上贡献分块. 考虑点分治算法 不妨先把题目简 ...

  7. BZOJ3924 ZJOI2015 幻想乡战略游戏 【动态点分治】

    BZOJ3924 ZJOI2015 幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂 ...

  8. AC日记——[ZJOI2015]幻想乡战略游戏 洛谷 P3345

    [ZJOI2015]幻想乡战略游戏 思路: 树剖暴力转移: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1 ...

  9. 【BZOJ3924】[Zjoi2015]幻想乡战略游戏 动态树分治

    [BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...

随机推荐

  1. 腾讯云Centos安装jdk8

    1.下载jdk1.8的tar cd /usr/local/src #切换到该目录下 wget url #下载jdk8的tar包 2.下载完成后解压tar包 tar -zxvf jdk-8u152-li ...

  2. LeetCode题解之Unique Paths

    1.题目描述 2. 问题分析 使用动态规划求解 3.代码 int uniquePaths(int m, int n) { vector<vector<)); ; i < m; i++ ...

  3. sqlserver tablediff 实用工具

    tablediff 是sqlserver自带的实用工具 sqlserver 2012 在110目录下,sqlserver2008在100目录下 官方参考文档如下: https://docs.micro ...

  4. 超经典sql练习题,在teradata上实现

    题目来源:https://blog.csdn.net/flycat296/article/details/63681089 teradata实现: drop table student; create ...

  5. MySQL大数据表水平分区优化的详细步骤

    将运行中的大表修改为分区表 本文章代码仅限于以数据时间按月水平分区,其他需求可自行修改代码实现 1. 创建一张分区表 这张表的表字段和原表的字段一摸一样,附带分区 1 2 3 4 5 6 7 8 9 ...

  6. 修改centos等linux的hostname-永久生效

    步骤uname -a (或者hostname)可以看到hostname,修改步骤如下: uname -a 查看hostnamehostname newname 修改下,让hostname立刻生效.vi ...

  7. teradata 数据定义

    teradata 数据定义 创建表的可选项 是否允许记录重复 set 不允许记录重复 multiset 允许记录重复 数据保护 fallback       fallback    使用fallbac ...

  8. 怎样在 fedora 28 上 打开 .jnlp 文件

    最近使用 iDrac 和 iLO 总是会使用到 .jnlp 文件, 为了方便,今天把设置过程记录下来. JNLP 文件,全名为 Java Network Launching Protocol 文件, ...

  9. UI中新增一个右击按钮的过程

    1.首先给出增加之后的成品 点击后的界面 3.需要增加的部分 新增一个类:DiglogAddUser  用于操作用户填写的数据,写入数据库等操作 3.1首先在资源文件中定义窗口代号 3.2 枚举出该代 ...

  10. 2018.09.01 09:22 Exodus

    Be careful when writing in the blog garden. Sometimes you accidentally write something wrong, and yo ...