题目:

  

题解:

  对点分树理解加深了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]幻想乡战略游戏的更多相关文章

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

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

  2. bzoj 3924 [Zjoi2015]幻想乡战略游戏——动态点分治(暴力移动找重心)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3924 度数只有20,所以从一个点暴力枚举其出边,就能知道往哪个方向走. 知道方向之后直接走到 ...

  3. BZOJ 3924 ZJOI2015 幻想乡战略游戏 树链剖分

    题目链接:https://www.luogu.org/problemnew/show/P3345(bzoj权限题) 题意概述:动态维护树的上所有点到这棵树的带权重心的距离和.N,Q<=10000 ...

  4. BZOJ 3924: [Zjoi2015]幻想乡战略游戏(动态点分治)

    这种动态点分治嘛,GDKOI时听打到了,也有同学讲到了,所以印象比较深刻也就想出来了,然后就在实现方面卡了好久= = 不得不说CLJ说得真的太简单了,实现方面根本没提. 首先我们可以先用树分治构建出这 ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. css3属性(1)

    text-transform语法: text-transform : none | capitalize| uppercase| lowercase 参数: none : 无转换发生 capitali ...

  2. Java——面向对象 this关键字

    this,当成员变量和局部变量名字重名时,可以用关键字来区分. this 代表当前对象,就是所在函数所属的对象的引用. 即哪个调用了this所在的函数,this就代表哪个函数. 应用:1,构造方法间的 ...

  3. 星云链开发dapp,赚取100nas(价值近万)

    前几天星云链主网正式上线,现在只要成功提交一个dapp即可获得100nas,1个nas 75元人民币左右.编写合约只要会javascript就可以写.活动持续两个月左右.下面简单介绍一下流程 首先注册 ...

  4. MySQL中遇到的几种报错及其解决方法

    MySQL中遇到的几种报错及其解决方法 1.[Err] 1064 - You have an error in your SQL syntax; check the manual that corre ...

  5. Application "org.eclipse.ui.ide.workbench" could not be found in the registry.问题的解决

    今天升级Eclipse,升级完Restart,碰到启动不了让看日志,日志里主要错误信息即是Application "org.eclipse.ui.ide.workbench" co ...

  6. A million requests per second with Python

    https://medium.freecodecamp.com/million-requests-per-second-with-Python-95c137af319 Is it possible t ...

  7. 简单而强大的bitset

    简单而强大的bitset 介绍 有些程序需要处理二进制有序集,标准库提供了bitset 类型,事实上,bitset 是一个二进制容器,容器中每一个元素都是一位二进制码,或为 0,或为 1. 基础 bi ...

  8. (转)java之Spring(IOC)注解装配Bean详解

    java之Spring(IOC)注解装配Bean详解   在这里我们要详细说明一下利用Annotation-注解来装配Bean. 因为如果你学会了注解,你就再也不愿意去手动配置xml文件了,下面就看看 ...

  9. 第二章 ArrayList源码解析

    一.对于ArrayList需要掌握的七点内容 ArrayList的创建:即构造器 往ArrayList中添加对象:即add(E)方法 获取ArrayList中的单个对象:即get(int index) ...

  10. JQuery制作基础的无缝轮播与左右点击效果

    在网页中我们想要的无缝轮播左右循环有好多好多中,这是我第一个轮播效果,也是最基础的,和大家分享一下,对于初学者希望你们能有所借鉴,对于大神我想让你们尽情的虐我给我宝贵的意见. 这个是我要的效果 进入正 ...