【BZOJ 3924】[Zjoi2015]幻想乡战略游戏
题目:
题解:
对点分树理解加深了233,膜拜zzh干翻紫荆花。
感谢zzh的讲解。
首先优化基于传统DP,假设树不发生变化,我们就可以利用DP求出带权重心。
考虑修改,我们思路不变,还是从root开始找,但发现这样会被卡成$n^2$,原因是每次经过点太多,为了优化,考虑点分树,由于点分树的性质使得假设我们可以在点分树上找到最优解,那么每次最多经过$log$个节点,可以保证时间复杂度。
然后考虑在点分树转移,假设当前节点为x,我们枚举其在原树中的边,假设当前枚举边的另一端为y,那么由DP可以得出如果以当前边分为两半,若y的一半点权和大于所有点权的一半,那么最优解一定在y那边存在,然后我们由点分树直接跳跃到y对应的块中。若不存在这样的y,则x一定为最优解。
这样的话我们的目的就是求x点对应的答案以及y一边对应的点权和,我们用三个数组来记录当前x的点分子树的点权和,点分子树到达x的$d*dis$和,以及到达其父亲的$d*dis$和,这样统计x的答案就可以在$log$的时间内完成。
对于y我们可以开一个$log$大小的数组来记录在点分数上走过的点,并按照原树dfs排序,每次到达一个新的x用$log$更新,并在此序列上维护一个$sum$表示经过路径上x与其儿子s点权和之差,那么考虑若枚举的y是x在原树的儿子或父亲时的情况,分类讨论,利用$sum$快速求出y一边的点权和。
综上所述,时间复杂度为$O(20nlog_2^nlog_2^{log_2^n})$
代码:
#define Troy
#define inf 0x7fffffff #include "bits/stdc++.h" using namespace std; inline int read(){
int s=,k=;char ch=getchar();
while (ch<''|ch>'') ch=='-'?k=-:,ch=getchar();
while (ch>&ch<='') s=s*+(ch^),ch=getchar();
return s*k;
} const int N=1e5+; typedef long long ll; struct edges {
int v,nv,w;edges *last;
}edge[N<<],*head[N];int cnt; inline void push(int u,int v,int w){
edge[++cnt]=(edges){v,,w,head[u]};head[u]=edge+cnt;
} int bit[]; class ST{
public:
inline void build(int *a,int n){
lgs[]=-;
register int i,j;
for (i=;i<=n;++i) lgs[i]=lgs[i>>]+,f[i][]=a[i];
for (i=;bit[i]<=n;++i)
for (j=;j+bit[i]<=n+;++j)
f[j][i]=min(f[j][i-],f[j+bit[i-]][i-]);
} inline int query(int l,int r){
if(r<l) swap(l,r);int t=lgs[r-l+];
return min(f[l][t],f[r-bit[t]+][t]);
}
private:
int f[N<<][],lgs[N<<];
}RMQ; int dis[N],eular[N<<],num,beg[N],End[N],n,m; inline void DFS(int x,int fa){
eular[beg[x]=++num]=dis[x];
for(edges *i=head[x];i;i=i->last) if(i->v^fa){
dis[i->v]=dis[x]+i->w;
DFS(i->v,x);
eular[++num]=dis[x];
}End[x]=num;
} inline ll get_dis(int x,int y){
return dis[x]+dis[y]-(RMQ.query(beg[x],beg[y])<<);
} class Point_Divide_Tree{
public:
int root,tot,fat[N],size[N],heavy[N],dsum[N];
bool vis[N];
ll dissum[N],fdissum[N]; inline void dfs(int x,int fa){
size[x]=,heavy[x]=;
for(edges *i=head[x];i;i=i->last) if(i->v!=fa&&!vis[i->v]){
dfs(i->v,x),size[x]+=size[i->v];
heavy[x]=max(heavy[x],size[i->v]);
}heavy[x]=max(heavy[x],tot-size[x]);
if(heavy[root]>heavy[x]) root=x;
} inline void build(int x,int fa){
root=,dfs(x,);
vis[x=root]=true,fat[x]=fa,dfs(x,x);
for (edges *i=head[x];i;i=i->last) if(!vis[i->v]){
tot=size[i->v];
build(i->v,x),i->nv=root;
}root=x;
} inline void insert(int x,int y,int val){
tot+=val;
while(x){
dsum[x]+=val;
dissum[x]+=get_dis(x,y)*val;
if(fat[x])
fdissum[x]+=get_dis(fat[x],y)*val;
x=fat[x];
}
} ll ans,sum[];
int pos[],leth; inline int calc(int fa,int x,int real){
int ret=dsum[real];
if(dis[x]<dis[fa]){
int l=lower_bound(pos+,pos+leth+,beg[fa])-pos,
r=upper_bound(pos+,pos+leth+,End[fa])-pos-;
ret+=sum[leth]-sum[r]+sum[l-];
}else{
int l=lower_bound(pos+,pos+leth+,beg[x])-pos,
r=upper_bound(pos+,pos+leth+,End[x])-pos-;
ret+=sum[r]-sum[l-];
}
return ret;
} inline ll calc(int x){
ll ret=dissum[x];
int p=x;
while(fat[x]){
ret+=(dsum[fat[x]]-dsum[x])*get_dis(fat[x],p)+dissum[fat[x]]-fdissum[x];
x=fat[x];
}return ret;
} inline void update(int x,int y){
ll now=dsum[x]-dsum[y];
for(int i=leth+;i;--i){
sum[i]=sum[i-]+now;
if(i==||pos[i-]<=beg[x]){
pos[i]=beg[x];
break;
}else pos[i]=pos[i-];
}++leth;
} inline void query(int x){
for(edges *i=head[x];i;i=i->last) if(i->nv){
if(calc(x,i->v,i->nv)*>=tot){
update(x,i->nv);
ans=calc(i->nv);
query(i->nv);
break;
}
}
} inline void query(){
leth=;
ans=dissum[root];
query(root);
printf("%lld\n",ans);
}
}tree; int main(){
register int i,j;
for (i=;i<=;++i) bit[i]=<<i;
n=read(),m=read();
for (i=;i^n;++i){
int a=read(),b=read(),c=read();
push(a,b,c),push(b,a,c);
}
DFS(,),RMQ.build(eular,num);
tree.tot=n,tree.heavy[]=inf;
tree.build(,),tree.tot=;
while(m--){
i=read(),j=read();
tree.insert(i,i,j);
tree.query();
}
}
【BZOJ 3924】[Zjoi2015]幻想乡战略游戏的更多相关文章
- bzoj 3924: [Zjoi2015]幻想乡战略游戏
Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来, ...
- bzoj 3924 [Zjoi2015]幻想乡战略游戏——动态点分治(暴力移动找重心)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3924 度数只有20,所以从一个点暴力枚举其出边,就能知道往哪个方向走. 知道方向之后直接走到 ...
- BZOJ 3924 ZJOI2015 幻想乡战略游戏 树链剖分
题目链接:https://www.luogu.org/problemnew/show/P3345(bzoj权限题) 题意概述:动态维护树的上所有点到这棵树的带权重心的距离和.N,Q<=10000 ...
- BZOJ 3924: [Zjoi2015]幻想乡战略游戏(动态点分治)
这种动态点分治嘛,GDKOI时听打到了,也有同学讲到了,所以印象比较深刻也就想出来了,然后就在实现方面卡了好久= = 不得不说CLJ说得真的太简单了,实现方面根本没提. 首先我们可以先用树分治构建出这 ...
- bzoj3924 [Zjoi2015]幻想乡战略游戏 点分树,动态点分
[BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...
- 洛谷 P3345 [ZJOI2015]幻想乡战略游戏 解题报告
P3345 [ZJOI2015]幻想乡战略游戏 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做 ...
- [ZJOI2015]幻想乡战略游戏——动态点分治
[ZJOI2015]幻想乡战略游戏 带修改下,边点都带权的重心 随着变动的过程中,一些子树内的点经过会经过一些公共边.考虑能不能对这样的子树一起统计. 把树上贡献分块. 考虑点分治算法 不妨先把题目简 ...
- BZOJ3924 ZJOI2015 幻想乡战略游戏 【动态点分治】
BZOJ3924 ZJOI2015 幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂 ...
- AC日记——[ZJOI2015]幻想乡战略游戏 洛谷 P3345
[ZJOI2015]幻想乡战略游戏 思路: 树剖暴力转移: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1 ...
- 【BZOJ3924】[Zjoi2015]幻想乡战略游戏 动态树分治
[BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...
随机推荐
- 学习jQuery必须知道的几种常用方法
jQuery事件处理 ready(fn) 代码: $(document).ready(function(){ // Your code here...}): 作用:它可以极大地提高web应用程序的响 ...
- OO开发思想:面向对象的开发方法(Object oriented,OO)
面向对象的开发方法(Object oriented,OO)认为是好文章吧,拿来分享一下(转载) 面向对象的开发方法(Object oriented,OO) 从事软件开发的工程 师们常常有这样 的体会: ...
- zabbix 批量生成聚合图形
通过插入数据库的方式批量生成 zabbix 聚合图形 原型图形 聚合的 sql 批量操作 .在聚合图形创建好一个聚合图形A.找出图形A的ID (创建图形的时候记得填写好行数和列数) select sc ...
- php namespace与use
实验代码 ~/aa.php ~/bb.php 1.命名空间与文件加载的关系 本人在命名空间与文件加载上一直有一个误区,用了命名空间文件不用加载了? 实验1:去掉requre语句 可以看到就算使用命名空 ...
- Java中常用的数据结构类
结构体系图 List ArrayList.LinkedList.Vector有什么区别? ArrayList 只能装入引用对象(基本类型要转换为封装类): 线程不安全: 底层由数组实现(顺序表),因为 ...
- The note of Developing Innovative Ideas for New Companies Course
This course is free on the Coursera Site,But it only has English version Threee pieces of the course ...
- 与班尼特·胡迪一起做生意 (HZUN-2261)
与班尼特·胡迪一起做生意 AC Time Limit: 1 s Memory Limit: 256 MB Description 马爷作为2-80X的资深土财主,靠着敏锐的商业嗅觉不断 ...
- SOFA 源码分析 — 扩展机制
前言 我们在之前的文章中已经稍微了解过 SOFA 的扩展机制,我们也说过,一个好的框架,必然是易于扩展的.那么 SOFA 具体是怎么实现的呢? 一起来看看. 如何使用? 看官方的 demo: 1.定义 ...
- Bootstrap在线引用css和js
百度在线调用 <script src="http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.min.js"></ ...
- C# 数据库链接字符串加密工具
有些项目尤其是WinForm或者是WPF项目,针对一些工具形式的小项目,不想软件流出去之后,懂程序的的拿到手之后一看配置文件就知道了我们数据库的用户名和密码,如果外网能访问的话,那就麻烦大了.所以这里 ...