传送门

Description

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

在打仗之前,幽香现在面临一个非常基本的管理问题需要解决。 整个地图是一个树结构,一共有\(n\)块空地,这些空地被\(n-1\)条带权边连接起来,使得每两个点之间有一条唯一的路径将它们连接起来。

在游戏中,幽香可能在空地上增加或者减少一些军队。同时,幽香可以在一个空地上放置一个补给站。 如果补给站在点\(u\)上,并且空地v上有\(dv\)个单位的军队,那么幽香每天就要花费\(dv*dist(u,v)\)的金钱来补给这些军队。

由于幽香需要补给所有的军队,因此幽香总共就要花费为\(\sum Dv*dist(u,v)\) (\(1\leq V \leq N\))的代价。其中\(dist(u,v)\)表示u个v在树上的距离(唯一路径的权和)。

因为游戏的规定,幽香只能选择一个空地作为补给站。在游戏的过程中,幽香可能会在某些空地上制造一些军队,也可能会减少某些空地上的军队,进行了这样的操作以后,出于经济上的考虑,幽香往往可以移动他的补给站从而省一些钱。

但是由于这个游戏的地图是在太大了,幽香无法轻易的进行最优的安排,你能帮帮她吗? 你可以假定一开始所有空地上都没有军队。

Solution

题意:树上点权修改,询问带权重心

大大加深了对点分树的理解?

首先,点分树有个性质:点分树上的两点的lca在原树的两点路径上,这样,我们通过记录点分树上一点到它的祖先的在原树上的距离,就可以得到任意两点在原树上的距离啦

带权重心是什么咧?

可以当做它是这样一个点,已这个点为根的每个子树的权重都不超过原树的总size的一半。

为什么?假如找到了这个点,那么无论把它移动进入哪个子树,代价都会变得更大,读者可以自行证明。

而我们用上面的做法,就可以得到树的带权重心。

对于这道题:

  • 先预处理出点分树,记录下每个点在点分树上的孩子和祖先以及和每个祖先的实际距离(便于以后查找)

  • 记录下点分树上每个节点,在原树上所代表的联通块的根节点\(HR\)(这里指的是深度最小的那个点)

    为什么要记录这个东西咧?

    因为我们在寻找带权重心的时候,每进入一个点,就要更改某些点的权重,因为要算上除了这个联通块外的权重,而需要更改的点就是这个\(HR\),可以理解为,它是这个联通块的边界

    当然找到重心后,你得把你做的更改全都改回来

  • 我们考虑每次更改会有什么影响,首先,总权重增加\(e\),点分树上的相关节点的总权重也会发生变化,还有就是要即使更新相关节点的代价和,具体的,加上\(e*dis\),这里的相关节点指的是修改节点的祖先节点(我们显然只需要记录它对祖先的贡献,根据点分树的性质)

  • 查询就是枚举这个点与重心的在点分树上的\(lca\),统计代价即可

因为点分树的深度不超过\(\log n\),所以总复杂度是\(O(n log^2 n)\)

Code 

#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
#define MN 100005
#define reg register
int n,m,en,hr[MN];
struct edge{int to,w,nex;}e[MN<<1];
inline void ins(int f,int t,int w)
{
e[++en]=(edge){t,w,hr[f]};hr[f]=en;
e[++en]=(edge){f,w,hr[t]};hr[t]=en;
}
bool vis[MN];
int rt,sm,siz[MN],dep[MN];
ll vsum,w[MN],val[MN];
struct Node{int id;ll dis;};
std::vector<Node> fa[MN],s[MN];
int HR[MN];
void pre_dfs(int x,int f)
{
reg int i;siz[x]=1;
for(i=hr[x];i;i=e[i].nex)if(!vis[e[i].to]&&(f^e[i].to))
pre_dfs(e[i].to,x),siz[x]+=siz[e[i].to];
}
void getroot(int x,int f)
{
reg int i;rt=x;
for(i=hr[x];i;i=e[i].nex)
if(!vis[e[i].to]&&(f^e[i].to)&&(siz[e[i].to]<<1)>=sm){getroot(e[i].to,x);break;}
}
void dfs(int x,int f,int ro)
{
fa[x].push_back((Node){ro,dep[x]});
reg int i;
for(i=hr[x];i;i=e[i].nex)if(!vis[e[i].to]&&(f^e[i].to))
dep[e[i].to]=dep[x]+e[i].w,dfs(e[i].to,x,ro);
}
inline void pre_work(int x=1,int f=0)
{
pre_dfs(x,f);
sm=siz[x];getroot(x,f);vis[rt]=true;
reg int i,j=rt;
s[f].push_back((Node){j,0LL});fa[j].push_back((Node){j,0LL});
HR[j]=x;
for(i=hr[rt];i;i=e[i].nex)
if(!vis[e[i].to]){dep[e[i].to]=e[i].w;dfs(e[i].to,j,j);pre_work(e[i].to,j);}
rt=j;
}
inline void Modify(int x,int y)
{
vsum+=y;val[x]+=y;reg int i,j=x,f,k;
for(i=fa[x].size()-1;~i;--i) w[fa[x][i].id]+=y;
for(i=fa[x].size()-2;~i;--i)
for(j=s[fa[x][i].id].size()-1;~j;--j)
if(s[fa[x][i].id][j].id==fa[x][i+1].id){s[fa[x][i].id][j].dis+=y*fa[x][i].dis;break;}
}
inline void upd(int x,int y){for(reg int i=fa[x].size()-1;~i;--i)w[fa[x][i].id]+=y;}
inline int Find(int x)
{
reg int ret=x,i,tmp;
for(i=s[x].size()-1;~i;--i)
if(w[s[x][i].id]*2>=vsum)
{
tmp=w[x]-w[s[x][i].id];
upd(HR[s[x][i].id],tmp);ret=Find(s[x][i].id);upd(HR[s[x][i].id],-tmp);
break;
}
return ret;
}
inline ll Query(int x)
{
reg ll ret=0;
reg int i,j,las=0;
for(i=fa[x].size()-1;~i;las=fa[x][i].id,--i)
{
ret+=fa[x][i].dis*val[fa[x][i].id];
for(j=s[fa[x][i].id].size()-1;~j;--j)
if(s[fa[x][i].id][j].id^las)
ret+=fa[x][i].dis*w[s[fa[x][i].id][j].id]+s[fa[x][i].id][j].dis;
}
return ret;
}
int main()
{
n=read();m=read();
register int i,x,y;
for(i=1;i<n;++i) x=read(),y=read(),ins(x,y,read());
pre_work();
while(m--)
{
x=read();y=read();Modify(x,y);
printf("%lld\n",Query(Find(rt)));
}
return 0;
}

Blog来自PaperCloud,未经允许,请勿转载,TKS!

luogu_P3345[zjoi2015]幻想乡战略游戏的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. BZOJ3924 [Zjoi2015]幻想乡战略游戏

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

  8. [ZJOI2015]幻想乡战略游戏

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

  9. bzoj 3924: [Zjoi2015]幻想乡战略游戏

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

随机推荐

  1. springboot笔记03——quickstart程序原理

    一.前言 一个quickstart程序仅仅让我们初步了解一个框架,我们还需要透过现象看本质才能学好一个框架.所以这篇文章分析一下我上次写的springboot的入门程序. 二.原理分析 1.依赖分析 ...

  2. Authorization Bypass in RSA NetWitness

    https://www.cnblogs.com/iAmSoScArEd/ SEC Consult Vulnerability Lab Security Advisory < 20190515-0 ...

  3. weblogic jdbc 相关概念介绍

    weblogic jdbc 是什么? 如何配置? 常见问题? 如何监控?

  4. MongoDB 无法启动

    提示 mongodb Mongod complains that there is no /data/db folder!! 解决方法:http://stackoverflow.com/questio ...

  5. lucene初探

    http://www.cnblogs.com/xing901022/p/3933675.html

  6. Linux之python3编译安装

    一,前言 centos7默认是装有python的,咱们先看一下 [root@glh ~ 20:18:03]#python Python 2.7.5 (default, Jul 13 2018, 13: ...

  7. WebApi增加Oauth2认证

    前期搭建可看这篇博文:https://www.cnblogs.com/lnice/p/6857203.html,此博文是在本篇博文实践才产生的,在实践中,也产生了几个问题,希望能够共同交流,一起进步. ...

  8. .NET Core 开发常用命令(VS Code)

    在开始开发 .NET Core 项目的时候,有用过 VS2017.VS Code 两个对比下来,VS 虽然开发更便捷但是 VS Code 更适合 .NET Core. 下面就总结一下常用的命令. 一. ...

  9. 男上加男团队对 修!咻咻! 团队,云打印 团队的Beta产品测试报告

    男上加男团队对 修!咻咻! 团队的Beta产品测试报告 男上加男团队对云打印 团队的Beta产品测试报告 6.2 1.57分补充 睡觉前看终于看到发布的在线版本 重新测试了一下 卡在注册这关 无法收到 ...

  10. Robot Framework--用例、数据、流程分离例子

    如果想改变输入框的输入词,则需要不停的复制case,为了减少冗余,可以做一个简单的分层,把搜索流程剥离成一个关键字,然后再不同的case中调用这个关键字,然后传递不同的参数,以进行不同数据在同一流程下 ...