【BZOJ 3924】【ZJOI 2015】幻想乡战略游戏
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】幻想乡战略游戏的更多相关文章
- [ZJOI 2015]幻想乡战略游戏
Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来, ...
- 【BZOJ 3924】[Zjoi2015]幻想乡战略游戏
题目: 题解: 对点分树理解加深了233,膜拜zzh干翻紫荆花. 感谢zzh的讲解. 首先优化基于传统DP,假设树不发生变化,我们就可以利用DP求出带权重心. 考虑修改,我们思路不变,还是从root开 ...
- ZJOI 2015 幻想乡战略游戏(动态点分治)
题意 https://loj.ac/problem/2135 思路 首先要明确一点,答案分布是有单调性的.什么意思呢?假设我们的答案在 \(u\) 节点,\((u,v)\) 之间有一条边且 \(u\) ...
- 解题:ZJOI 2015 幻想乡战略游戏
题面 神**所有点都爆int,我还以为我写出什么大锅了,不开long long见祖宗... 动态点分治利用点分树树高不超过log的性质,我们对每个点维护一个子树和,一个点分树子树和,一个点分树上父亲的 ...
- bzoj3924 [Zjoi2015]幻想乡战略游戏 点分树,动态点分
[BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...
- 【BZOJ3924】幻想乡战略游戏(动态点分治)
[BZOJ3924]幻想乡战略游戏(动态点分治) 题面 权限题...(穷死我了) 洛谷 题解 考虑不修改 发现一个贪心的做法 假设当前放在当前位置 如果它有一个子树的兵的总数大于总数的一半 那么,放到 ...
- LOJ2135 「ZJOI2015」幻想乡战略游戏
题意 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和 ...
- LOJ #2135. 「ZJOI2015」幻想乡战略游戏
#2135. 「ZJOI2015」幻想乡战略游戏 链接 分析: 动态点分治,求加权重心,带修改. 考虑如果知道了一个点s,如何求答案,那么首先可以点分治的思想,求每个联通块内所有点到分治中心距离和,然 ...
- 洛谷 P3345 [ZJOI2015]幻想乡战略游戏 解题报告
P3345 [ZJOI2015]幻想乡战略游戏 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做 ...
- [ZJOI2015]幻想乡战略游戏——动态点分治
[ZJOI2015]幻想乡战略游戏 带修改下,边点都带权的重心 随着变动的过程中,一些子树内的点经过会经过一些公共边.考虑能不能对这样的子树一起统计. 把树上贡献分块. 考虑点分治算法 不妨先把题目简 ...
随机推荐
- 控制 Cookie 的作用范围
默认时,网站的所有 Cookies 都一起被存储在客户端,并且所有 Cookies 连同网站的任何请求一起被发送到服务器.换句话说,网站中的每个页面都能够为网站获取所有的 Cookies.但是,你能够 ...
- Perl6 Bailador框架(5):利用正则匹配路径
use v6; use Bailador; =begin pod 我们在路径设置上, 可以利正则表达式捕获的字符串作为子例程参数 =end pod get '/perl6/(.+)' => su ...
- Linux后台研发面试题
本系列给出了在复习过程中一些C++后台相关面试题,回答内容按照笔者的知识点掌握,故有些问题回答较为简略 1.信号的生命周期 一个完整的信号生命周期可以用四个事件刻画:1)信号诞生:2)信号在进程中注册 ...
- python基础===新式类与经典类
首先: Python 2.x中默认都是经典类,只有显式继承了object才是新式类 Python 3.x中默认都是新式类,不必显式的继承object 这两种类的区别: 新式类重定义的方法更多,当然这不 ...
- quazip 在windows msvc 2005 下的编译
quazip 在windows msvc 2005 下的编译 http://blog.csdn.net/v6543210/article/details/11661427
- C高级 框架开发中红黑树结构
引言 -- 红黑树历史 红黑树是数据结构学习中一道卡. 底层库容器中必不可少的算法. 历经各种实战运用,性能有保障. 同样红黑树不好理解, 就算理解了, 代码也不好写. 就算写了, 工程库也难构建. ...
- 运输层和TCP/IP协议
0. 基本要点 运输层是为相互通信的应用进程提供逻辑通信. 端口和套接字的意义 什么是无连接UDP 什么是面向连接的TCP 在不可靠的网络上实现可靠传输的工作原理,停止等待协议和ARQ协议 TCP的滑 ...
- 全国省市区数据SQL - 省市区
转载:https://www.cnblogs.com/flywind/p/6036801.html
- Fel表达式实践
项目背景 订单完成后,会由交易系统推送实时MQ消息给订单清算系统,告诉清算系统此订单交易完成,可以进行给商家结算等后续操作. 财务要求在交易推送订单到清算系统时和订单清算系统接收到订单消息后,需要按照 ...
- 并发容器ConcurrentHashMap与synchronized联合使用达到线程安全
http://blog.csdn.net/yansong_8686/article/details/50664338 map.put(KEY, map.get(KEY) + 1); 实际上并不是原子操 ...