题目大意:
有边权点权的树,动态修改点权
每次修改后求带权重心x (\(minimize\) \(S=\sum_i val[i]*dist[x][i]\))
分析:
从暴力找突破口:
对于边x,y,设长度为len,切断后x半边树权值和为\(w_1\),y半边树为\(w_2\)
若从重心从x转到到y,则\(S+w_1*len-w_2*len\)
y比x优当且仅当\(w_2>w_1\)
设当前根为root,若root的一儿子x,满足\(w_x>w_{root}-w_x\),则x更优,且可以证明\(w_x>\frac {w_{root}} 2\),即不会存在第二个儿子y也比root优
做法:
暴力做法深度无保证,但\(w_x>w_{root}-w_x\)可以确定答案在x子树
我们用点分治树保证深度
新的问题:点分治树怎么求w
对于边x,y,设x半边树中所有点到x距离为\(d_1\),y半边树中所有点到y距离为\(d_2\)
所有点到x距离为\(d_1+d_2+w_2*len\)
所有点到y距离为\(d_1+d_2+w_1*len\)
可以了啊,这就是动态点分治模板了
询问复杂度\(nlog^2n\)
==============================================================================================
后来信息队一位善于创新的大神想到了nlogn的方法
x为rt,y为点分儿子时
x在上则两边权值和分别为w(y)和w(root)-w(y)
y在上则两边权值和分别为w(root)-w(x)+w(y)和w(x)-w(y)
乍一看非常正确,用rmq求个lca就可以O(1)判上下,超简便维护
但如果如图 :

兜来兜去的图发现bug多多
吸取经验

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long LL;
const int M=100007;
const int N=M*20*2;
inline int rd(){int x=0;bool f=1;char c=getchar();for(;!isdigit(c);c=getchar())if(c=='-')f=0;for(;isdigit(c);c=getchar())x=x*10+c-48;return f?x:-x;
}int n,m;int g[M],te;
struct edge{int y,next;LL d;
}e[M<<1];
void addedge(int x,int y,LL d){e[++te].y=y;e[te].d=d;e[te].next=g[x];g[x]=te;
}int fir[M],td;
struct down{int y;//点分儿子int son;//亲儿子int next;
}dw[M];
void adddw(int x,int y,int son){dw[++td].y=y;dw[td].son=son;dw[td].next=fir[x];fir[x]=td;
}int hd[M],tu;
struct uppp{int all,sub,next;LL dis;
}up[N];
void addup(int x,int all,int sub,LL dis){up[++tu].all=all;up[tu].sub=sub;up[tu].dis=dis;up[tu].next=hd[x];hd[x]=tu;
}struct node{LL sum,val;
}a[M<<1];
int idrt,idsub,nw;int sz[M],vis[M];
int mi,size,rt,root;void getsz(int x,int fa){sz[x]=1;int p,y;for(p=g[x];p;p=e[p].next)if(!vis[y=e[p].y]&&y!=fa){getsz(y,x);sz[x]+=sz[y];}
}void getrt(int x,int fa){int f,p,y;f=size-sz[x];for(p=g[x];p;p=e[p].next)if(!vis[y=e[p].y]&&y!=fa){getrt(y,x);f=max(f,sz[y]);}if(f<mi) mi=f,rt=x;
}void dfs(int x,int fa,LL dis){addup(x,idrt,idsub,dis);int p,y;for(p=g[x];p;p=e[p].next)if(!vis[y=e[p].y]&&y!=fa){dfs(y,x,dis+e[p].d);}
}void work(int frm,int drt){getsz(frm,0);mi=size=sz[frm];getrt(frm,0);int x=rt,p,y;vis[x]=1;idrt=++nw;addup(x,idrt,-1,0);if(drt) adddw(drt,x,frm);else root=x;for(p=g[x];p;p=e[p].next)if(!vis[y=e[p].y]){idsub=++nw;dfs(y,x,e[p].d);}for(p=g[x];p;p=e[p].next)if(!vis[y=e[p].y]) work(y,x);
}void update(int x,LL y){int p;for(p=hd[x];p;p=up[p].next){a[up[p].all].val+=y;a[up[p].all].sum+=y*up[p].dis;if(up[p].sub!=-1){a[up[p].sub].val+=y;a[up[p].sub].sum+=y*up[p].dis;}}
}LL get(int x){LL res=0;int p;for(p=hd[x];p;p=up[p].next){res+=a[up[p].all].sum;res+=a[up[p].all].val*up[p].dis;if(up[p].sub!=-1){res-=a[up[p].sub].sum;res-=a[up[p].sub].val*up[p].dis;}}return res;
}int anst;
void find(int x){int p,y,bb=1;for(p=fir[x];p;p=dw[p].next)if(get(x)>=get(dw[p].son)){bb=0;find(dw[p].y);break;}if(bb) anst=x;
}int main(){int i,x,y,z;n=rd();m=rd();for(i=1;i<n;i++){x=rd(),y=rd(),z=rd();addedge(x,y,z);addedge(y,x,z);}work(1,0);for(i=1;i<=m;i++){x=rd(),y=rd();update(x,y);find(root);printf("%lld\n",get(anst));}return 0;
}

转载于:https://www.cnblogs.com/acha/p/6283355.html

bzoj 3924 幻想乡战略游戏相关推荐

  1. P3345 [ZJOI2015]幻想乡战略游戏

    P3345 [ZJOI2015]幻想乡战略游戏 带修改带权重心 这是经典的树上寻找关键点的题目,我们使用点分治处理这个问题,因为点分治的特性,就相当于在树上二分了.但是这与倍增不同,倍增只是在链上二分 ...

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

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

  3. [ZJOI2015] 幻想乡战略游戏——树链剖分

    [ZJOI2015]幻想乡战略游戏 题解 由于所有边的边权是正整数,所以可以发现任何时刻每个点的答案是从最优的点往周围递增的.如果有平台,那么一定是在最优点的连通块那儿. 我们先考虑如何快速求每个点的 ...

  4. 【bzoj3924】[Zjoi2015]幻想乡战略游戏 动态点分治

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

  5. Bzoj3924 [Zjoi2015]幻想乡战略游戏

    Time Limit: 100 Sec  Memory Limit: 256 MB Submit: 817  Solved: 376 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏 ...

  6. luogu_P3345[zjoi2015]幻想乡战略游戏

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

  7. [zjoi2015]幻想乡战略游戏

    前言 略略略 题目相关 链接 题目大意 给出一棵树,每次修改一个点的权值,维护一个带权重心 啥是带权重心? 设点iii的值为ViV_iVi​我们要选一个点uuu,每个点对应一个值: ∑v=1nVv∗d ...

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

    对于一个点,要求出它到所有点的带权距离和,只需记录下树分治的结构然后查询即可. 修改$O(\log n)$,查询$O(\log n)$. 到所有点带权距离和最小的点显然是这棵树的带权重心. 以1号点为 ...

  9. 【ZJOI2015】幻想乡战略游戏【点分树】【带权重心】

    题意:nnn个点带边权的树,动态修改点权viv_ivi​,最小化 钦定一个点xxx 后 ∑idist(x,i)∗vi\sum\limits_{i} dist(x,i)*v_ii∑​dist(x,i)∗ ...

最新文章

  1. Auth模块、Forms组件
  2. CTFshow 爆破 web21
  3. python多核多线程编程_python是否支持多处理器/多核编程?
  4. 逆天Kali带你游遍大江南北~安全之前人铺路!
  5. 《MS SQL Server 2000管理员手册》系列——8. 管理 Microsoft SQL Server 服务
  6. oracle pl/sql 面试,Oracle SQL 面试题(整理)
  7. Android手机产线测试模块,基于Android平台智能手机可靠性生产测试模式的实现
  8. IOT(22)---NB-IoT、LoRa产业组织格局
  9. Ubuntu中创建、删除、更改、移动文件的命令
  10. Jenkins 官网文档翻译汇总
  11. c++写入二进制、TXT文件,读取二进制、TXT文件,切分字符串(入数组)
  12. ie11 java提示升级,解决IE11安装升级失败和在安装前需要更新的问题
  13. JMeter-配置元件-HTTP授权管理器
  14. One PUNCH Man——特征选择
  15. 异常报错原因及解决方案
  16. unity 鼠标放置 ui_ui层次结构以及不常见但至关重要的任务放置在哪里
  17. mysql如何盈利_mysql到底是不是免费的?
  18. 识别不了移动硬盘的解决方法
  19. Linux基础入门之内外命令讲解篇
  20. 2018年刑侦科推理试题php版,2018年刑侦科推理试题

热门文章

  1. 软件工程之系统顺序图
  2. 创业不要把大公司当直接对手
  3. 利用 Docker 搭建单机的 Cloudera CDH 以及使用实践
  4. 逻辑回归(Logistic Regression, LR)又称为逻辑回归分析,是分类和预测算法中的一种。通过历史数据的表现对未来结果发生的概率进行预测。例如,我们可以将购买的概率设置为因变量,将用户的
  5. 阿里云天池 金融风控训练营Task1 广东工业站
  6. sql的split()函数
  7. 谢烟客---------Linux之DNS服务系统的基础知识
  8. Git submodule 的笔记
  9. BZOJ 4811 树链剖分+线段树
  10. python为类定义构造函数