http://www.lydsy.com/JudgeOnline/problem.php?id=3924

gty的测试题,不会动态点分治而且看不出来链剖做法而且暴力打残所以这道题喜闻乐见的爆零了qwq

动态点分治:设重心重构树上以x为根的子树为\(T_x\),在重心重构树上每个点维护3个值。

\(sum(x)=\sum\limits_{u\in T_x}d(u)\)

\(ans(x)=\sum\limits_{u\in T_x}d(u)*dis(u,x)\)

\(ans\_fa(x)=\sum\limits_{u\in T_x}d(u)*dis(u,fa(x))\)

其中,\(dis\)指的是原树上的两点间距离,这个可以用st表\(O(1)\)求出;\(fa(x)\)指的是重心重构树上x的父亲。

每次修改x时,在重心重构树上不断地往上跳同时维护这三个值就可以了。

要查询一个点的花费(这里的花费指的在整棵树上的花费),类似修改,从重心重构树上不断地往上跳并统计答案(\(ans\_fa\)很明显是用来减掉自身贡献的)。

查询时从重心重构树的树根开始,枚举当前点在原树上连向更小分治块的边,检查这些边直接连着的点的花费。要是没有比当前点小的,答案就是当前点的花费;否则当前点跳到此时花费最小的点所在的下一级分治块的重心,继续检查。

感性理解:因为任意一条链上的点的花费是单峰的(峰向下),每次都向峰靠拢,所以这么做是正确的。

又因为重心重构树的树高是\(O(\log n)\)的,查询一个点的花费的时间复杂度是\(O(\log n)\),所以总时间复杂度是\(O(n\log n+q\log^2n*d)\)。

d指的是检查的所有点的平均度数,因为cls原题面中说明了每个点的度不超过20,所以这样可过。

这道题适合做动态点分治的模板题啊qwq

#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 100003; namespace RE {
struct node {int nxt, to, w;} E[N];
int cnt = 0, point[N], fa[N];
ll sum[N], ans[N], ans_fa[N];
void ins(int u, int v) {E[++cnt] = (node) {point[u], v}; point[u] = cnt; fa[v] = u;}
} namespace ORG {
struct node {int nxt, to, w;} E[N << 1];
int cnt = 0, point[N];
bool vis[N];
vector <pair <int, int> > ref[N];
void ins(int u, int v, int e) {E[++cnt] = (node) {point[u], v, e}; point[u] = cnt;} int qu[N], fa[N], sz[N];
int findrt(int x) {
fa[qu[1] = x] = 0;
int p = 0, q = 1, u;
while (p != q) {
sz[u = qu[++p]] = 0;
for (int i = point[u]; i; i = E[i].nxt)
if (E[i].to != fa[u] && !vis[E[i].to])
fa[E[i].to] = u, qu[++q] = E[i].to;
} for (int i = q; i >= 1; --i) {
sz[fa[qu[i]]] += (++sz[qu[i]]);
if ((sz[qu[i]] << 1) > q)
return qu[i];
}
} int root;
void dfs(int x) {
vis[x] = true;
for (int i = point[x]; i; i = E[i].nxt)
if (!vis[E[i].to]) {
root = findrt(E[i].to);
ref[x].push_back(make_pair(E[i].to, root));
RE::ins(x, root);
dfs(root);
}
} int L[N], wat[N << 1], tt = 0;
ll f[N << 1][19], deep[N]; void dfs2(int x, int ff) {
wat[L[x] = ++tt] = x;
for (int i = point[x]; i; i = E[i].nxt)
if (E[i].to != ff) {
deep[E[i].to] = deep[x] + E[i].w;
dfs2(E[i].to, x);
wat[++tt] = x;
}
} int Log_2[N << 1], rt;
void pre() {
dfs2(1, 0);
Log_2[1] = 0; int cc = 0;
for (int i = 2; i <= tt; ++i) {
Log_2[i] = cc;
if ((1 << (cc + 1)) == i)
++cc;
}
for (int i = 1; i <= tt; ++i)
f[i][0] = deep[wat[i]];
for (int j = 1; j <= 18; ++j)
for (int i = (1 << j); i <= tt; ++i)
f[i][j] = min(f[i][j - 1], f[i - (1 << (j - 1))][j - 1]); rt = 1; while (RE::fa[rt]) rt = RE::fa[rt];
} int len;
ll dis(int x, int y) {
ll r = deep[x] + deep[y];
x = L[x]; y = L[y];
if (x > y) x ^= y ^= x ^= y;
len = Log_2[y - x + 1];
ll dlca = min(f[y][len], f[x - 1 + (1 << len)][len]);
return r - (dlca << 1);
} ll query(int x) {
ll ret = RE::ans[x], retf;
int ff, tmp = x;
while (true) {
if ((ff = RE::fa[tmp]) == 0) return ret;
retf = RE::ans[ff] - RE::ans_fa[tmp];
ret += retf + (RE::sum[ff] - RE::sum[tmp]) * dis(x, ff);
tmp = ff;
}
} void change(int x, int e) {
int tmp = x;
while (true) {
RE::sum[tmp] += e;
RE::ans[tmp] += dis(x, tmp) * e;
if (RE::fa[tmp]) {
RE::ans_fa[tmp] += dis(x, RE::fa[tmp]) * e;
tmp = RE::fa[tmp];
} else
return;
}
} ll ansit() {
int tmp = rt, an = tmp, len;
pair <int, int> ann;
ll annow, cmpan, rr;
while (true) {
cmpan = annow = query(tmp);
for (int i = 0, len = ref[tmp].size(); i < len; ++i)
if ((rr = query(ref[tmp][i].first)) < annow)
annow = rr, ann = ref[tmp][i];
if (annow != cmpan)
tmp = ann.second;
else
return annow;
}
}
} int n; int main() {
int q;
scanf("%d%d", &n, &q);
int u, v, e;
for (int i = 1; i < n; ++i) {
scanf("%d%d%d", &u, &v, &e);
ORG::ins(u, v, e);
ORG::ins(v, u, e);
} ORG::dfs(ORG::findrt(1));
ORG::pre(); while (q--) {
scanf("%d%d", &u, &e);
ORG::change(u, e);
printf("%lld\n", ORG::ansit());
}
return 0;
}

【BZOJ 3924】【ZJOI 2015】幻想乡战略游戏的更多相关文章

  1. [ZJOI 2015]幻想乡战略游戏

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

  2. 【BZOJ 3924】[Zjoi2015]幻想乡战略游戏

    题目: 题解: 对点分树理解加深了233,膜拜zzh干翻紫荆花. 感谢zzh的讲解. 首先优化基于传统DP,假设树不发生变化,我们就可以利用DP求出带权重心. 考虑修改,我们思路不变,还是从root开 ...

  3. ZJOI 2015 幻想乡战略游戏(动态点分治)

    题意 https://loj.ac/problem/2135 思路 首先要明确一点,答案分布是有单调性的.什么意思呢?假设我们的答案在 \(u\) 节点,\((u,v)\) 之间有一条边且 \(u\) ...

  4. 解题:ZJOI 2015 幻想乡战略游戏

    题面 神**所有点都爆int,我还以为我写出什么大锅了,不开long long见祖宗... 动态点分治利用点分树树高不超过log的性质,我们对每个点维护一个子树和,一个点分树子树和,一个点分树上父亲的 ...

  5. bzoj3924 [Zjoi2015]幻想乡战略游戏 点分树,动态点分

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

  6. 【BZOJ3924】幻想乡战略游戏(动态点分治)

    [BZOJ3924]幻想乡战略游戏(动态点分治) 题面 权限题...(穷死我了) 洛谷 题解 考虑不修改 发现一个贪心的做法 假设当前放在当前位置 如果它有一个子树的兵的总数大于总数的一半 那么,放到 ...

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

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

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

    #2135. 「ZJOI2015」幻想乡战略游戏 链接 分析: 动态点分治,求加权重心,带修改. 考虑如果知道了一个点s,如何求答案,那么首先可以点分治的思想,求每个联通块内所有点到分治中心距离和,然 ...

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

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

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

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

随机推荐

  1. 教你 Shiro 整合 SpringBoot,避开各种坑(山东数漫江湖)

    依赖包 <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-sprin ...

  2. 【洛谷 P1073】 最优贸易 (Tarjan缩点+拓扑排序)

    题目链接 先\(Tarjan\)缩点,记录每个环内的最大值和最小值. 然后跑拓扑排序,\(Min[u]\)表示到\(u\)的最小值,\(ans[u]\)表示到\(u\)的答案,\(Min\)和\(an ...

  3. HDU 1203 I NEED A OFFER! (dp)

    题目链接 Problem Description Speakless很早就想出国,现在他已经考完了所有需要的考试,准备了所有要准备的材料,于是,便需要去申请学校了.要申请国外的任何大学,你都要交纳一定 ...

  4. 解决vue代码缩进报错问题 关闭ESlint

    前言 使用vue-cli来构建单页SPA应用,提示代码缩进报错 原因分析 通过查看package.json文件我们可以发现,在文件中默认安装了eslint-loader模块,eslint-loader ...

  5. 深入理解 JavaScript(五)

    根本没有“JSON 对象”这回事! 前言 写这篇文章的目的是经常看到开发人员说:把字符串转化为 JSON 对象,把 JSON 对象转化成字符串等类似的话题,所以把之前收藏的一篇老外的文章整理翻译了一下 ...

  6. 八大疯狂的HTML5 Canvas及WebGL动画效果——8 CRAZY ANIMATIONS WITH WEBGL AND HTML5 CANVAS【收藏】

    HTML5, WebGL and Javascript have changed the way animation used to be. Past few years, we can only a ...

  7. 64_g5

    golang-github-kr-text-devel-0-0.11.git6807e77.f..> 11-Feb-2017 07:48 14250 golang-github-kr-text- ...

  8. python之operator操作符函数

    operator函数主要分为以下几类:对象比较.逻辑比较.算术运算和序列操作. 举例: #python 3.4 >>> operator.eq(1,2)False >>& ...

  9. 【模板】BZOJ 1692:队列变换—后缀数组 Suffix Array

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1692 题意: 给出一个长度为N的字符串,每次可以从串头或串尾取一个字符,添加到新串中,使新串 ...

  10. 网站服务器压力Web性能测试(4):服务器压力Web性能测试小结

    1.Apache Bench,Webbench,http_load对网站压力Web性能进行测试时,为了得到更加客观和准确的数值,应该从远程访问.局域网访问和本地等多个方面进行全方位的测试.一般用127 ...