题意自己看。。。

思路

没想到今(昨)天刷着刷着点分治的水题,就刷出来了一个点分树。。。

然后就疯狂地找题解,代码,最后终于把它给弄懂了。

点分树——动态点分治,对于此题来说,我们设u为当前的补给站位置,v是它的一个儿子。同时设dis(i,j)为树上i点到j点的距离。cnti为以i为根的子树中d(也就是军队数)的总量

我们把补给站从u转移到v(假设u是树的根),答案的变化为dis(u,v)*(cntu-cntv)-dis(u,v)*cntv=dis(u,v)*(cntu-2*cntv)

所以当2*cntv>cntu把补给站转移v会使答案变优,一直这样操作下去,直到不管如何转移都无法使答案变优,当前点就是答案。

我们对于每一次修改都维护一下然后默认当前点为补给站且为当前树的根,然后像刚才一样转移补给站,就有了这个题的大体思路。

但这样肯定会爆炸啊(每次只会转移一步,复杂度和深度有关)

所以我们就可以用到点分树了。

我们利用点分治的方法(找重心作为根节点,然后递归处理子树)重新构建一颗树,称为分治树。

举个例子,比如说样例

(左为原树右为分治树)

这样我们就得到一颗深度为log的树。

这样我们转移就不会因为深度太大而GG了。

但是,这样一来的话因为树的结构不一样了,补给站的转移就会很难。因为一个点在分治树的儿子在原树中不一定和它直接相连

(之后我们的补给站的转移都是在分治树上进行的)

但还是有办法解决的。我们记录这这些东西。dis(i,j)为i,j在原树的距离。cnt[i]为分治树中以i为根的子树中有多少个d,sumi为分治树中以i为根的子树中所有的点j的dis(i,j)*dj之和,sumch(i,j)记录i点第j个儿子的sum。

我们现在讨论从u转移到它分治树中的一个子节点v,v是原来这颗子树中的重心但在原树中并不一定和u之间相连,我们设原树中直接和u相连的点是w。

因为把补给站转到v的时候要把v作为整棵树的根,只要把v所在子树之外的所有信息扔到w中然后递归就可以了。那怎么维护w的信息呢?

我们记录在v处记录下w和w与u这条边的权值c,然后我们在cntw处加上cnt[u]-cnt[v],然后在sumw处加上sum[u]-sumch(i,v)+(cnt[u]-cnt[v])*c;

最后答案就取sum[当前点]就行了。

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define int long long
const int N=1e5+;
struct son{int v,rv,w;};
struct node{int u,c,w;};
struct pre{int to,w;};
vector<son>ch[N];
vector<node>stack;
vector<pre>f[N];
vector<int>sumch[N];
int num,head[N];
int g[N],root,size[N],all,vis[N];
int realroot,sum[N],cnt[N],n,m;
struct edge{
int to,nxt,w;
}e[N*];
void add_edge(int u,int v,int w){
num++;
e[num].nxt=head[u];
e[num].to=v;
e[num].w=w;
head[u]=num;
}
int read(){
int sum=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){sum=sum*+ch-'';ch=getchar();}
return sum*f;
}
void getroot(int u,int f){
g[u]=;size[u]=;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==f||vis[v])continue;
getroot(v,u);
g[u]=max(g[u],size[v]);
size[u]+=size[v];
}
g[u]=max(g[u],all-size[u]);
if(g[u]<g[root])root=u;
}
void dfs(int u,int fa,int top,int w){
pre x;x.to=top;x.w=w;
f[u].push_back(x);
size[u]=;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(vis[v]||v==fa)continue;
dfs(v,u,top,w+e[i].w);
size[u]+=size[v];
}
}
void work(int u){
pre y;y.w=;y.to=u;
f[u].push_back(y);
vis[u]=;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(vis[v]==)continue;
dfs(v,,u,e[i].w);
root=,all=size[v];
getroot(v,);
son x;x.v=root;x.rv=v;x.w=e[i].w;
ch[u].push_back(x);
work(root);
}
}
void update(int u,int c,int w){
for(int i=;i<f[u].size();i++){
int v=f[u][i].to;
int L=f[u][i].w;
cnt[v]+=c;
sum[v]+=w+c*L;
if(i!=f[u].size()-)
for(int j=;j<ch[v].size();j++){
if(ch[v][j].v==f[u][i+].to)sumch[v][j]+=w+c*L;
}
}
}
int check(){
int now=realroot,mx;
stack.clear();
while(now){
mx=;
for(int i=;i<ch[now].size();i++)
if(cnt[ch[now][i].v]>cnt[ch[now][mx].v])mx=i;
if(ch[now].size()==||cnt[ch[now][mx].v]*<=cnt[now]){
int ans=sum[now];
for(int i=;i<stack.size();i++)
update(stack[i].u,stack[i].c,stack[i].w);
return ans;
}
int v=ch[now][mx].v;
node x;
x.u=ch[now][mx].rv;x.c=-(cnt[now]-cnt[v]);
x.w=-(sum[now]-sumch[now][mx]+(cnt[now]-cnt[v])*ch[now][mx].w);
stack.push_back(x);
update(x.u,-x.c,-x.w);
now=v;
}
}
signed main(){
n=read();m=read();
for(int i=;i<n;i++){
int u=read(),v=read(),w=read();
add_edge(u,v,w);add_edge(v,u,w);
}
g[]=n+;root=;all=n;
getroot(,);realroot=root;
work(root);
for(int i=;i<=n;i++)sumch[i]=vector<int>(ch[i].size(),);
while(m--){
int x=read(),y=read();
update(x,y,);
printf("%lld\n",check());
}
return ;
}

[ZJOI2015]幻想乡战略游戏(点分树)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. 2018.08.28 洛谷P3345 [ZJOI2015]幻想乡战略游戏(点分树)

    传送门 题目就是要求维护带权重心. 因此破题的关键点自然就是带权重心的性质. 这时发现直接找带权重心是O(n)的,考虑优化方案. 发现点分树的树高是logn级别的,并且对于以u为根的树,带权重心要么就 ...

  8. 【洛谷3345_BZOJ3924】[ZJOI2015]幻想乡战略游戏(点分树)

    大概有整整一个月没更博客了 -- 4 月为省选爆肝了一个月,最后压线进 B 队,也算给 NOIP2018 翻车到 316 分压线省一这个折磨了五个月的 debuff 画上了一个不算太差的句号.结果省选 ...

  9. BZOJ 3924 / Luogu P3345 [ZJOI2015]幻想乡战略游戏 (动态点分治/点分树)

    题意 树的结构不变,每个点有点权,每一条边有边权,有修改点权的操作,设xxx为树中一点.求∑idist(x,i)∗a[i]\sum_idist(x,i)*a[i]i∑​dist(x,i)∗a[i]的最 ...

随机推荐

  1. Xcode 下“ did not have any applicable content ”分析及解决

    问题的产生 a.新建项目时选的iPhone b.为了做成图片启动,按照惯例去掉了LaunchStoryboard的引用,建了个LaunchImage的资源,属性里随便勾了一个,找了张匹配的图拖了过去 ...

  2. face++算法工程实习生面试

    2018-01-11 算法工程实习生  自动化工具链方面 面试的知识点非常仔细,十分检验基本功底 1.自我介绍 2.算法题,leetcode 第一题 两数之和 问python中数组和字典的查找时间复杂 ...

  3. echarts的下载为excel小工具

    echarts自带有下载为图片的功能,但是没有下载为excel表格的功能,个人觉得下载为表格更为需要,所以写了个工具,此工具应用有局限性,只能用于柱形图和折线图,option的series要是如下形式 ...

  4. zTree -- jQuery 树插件实现点击文字展开子节点

    新版本的zTree是单击+号展开子项,点击文字选中该项,双击文字展开子项 项目用的是3.5版本的,如果要点击文字展开子项暂时没查到资料,自己琢磨了下 项目用的是jquery.ztree.core-3. ...

  5. GRUB 引导流程

    GRUB(bootloader)引导流程:  GRUB,GRand Unified Bootlader ,是一个来自GUN项目的多操作系统启动程序.GRUB是多启动规范的实现,它允许用户可以在计算机内 ...

  6. 解决locate无法使用的问题

    使用yum安装,locate的安装包名为mlocate 安装: yum -y install mlocate 更新: updatedb 无法使用:先下载

  7. SpringCloud 构建微服务架构-练习

    我使用的springboot的版本为2.0.2.RELEASE,这里概念性的东西我就不粘贴复制了,百度一下 都是 一.启动Eureka注册中心服务 1.新建springboot项目,pom.xml配置 ...

  8. ASP.NET-后台cookie与前台JQUERY解析cookie

    在controller中给cookie赋值 HttpCookie cookie =newHttpCookie("pageInfo"); cookie["page_inde ...

  9. Maven多模块项目搭建

    最近一直在思考如何能够更好的重用代码.减少重复劳动,之前有一篇文章通过导入JAR包的形式,可以重用部分形如util类的方法,但是这样的话,管理起来jar包,特别是协同工作,多项目情况下,管理JAR会出 ...

  10. Android学习之GridView图片布局适配经验

    開始解说这篇博客之前,我想问一下,当布局相似GridView这样的多列布局时,我们该怎么布局,才干更好的去适配呢? 扣张图来展示一下 比如这样的需求,三张图片均分屏幕 实现方法: 1.切图固定,比如是 ...