2018.08.28 洛谷P3345 [ZJOI2015]幻想乡战略游戏(点分树)
传送门
题目就是要求维护带权重心。
因此破题的关键点自然就是带权重心的性质。
这时发现直接找带权重心是O(n)的,考虑优化方案。
发现点分树的树高是logn级别的,并且对于以u为根的树,带权重心要么就是u,要么存在于u的某一个儿子为根的子树中。
由于带权重心只有一个,因此只需要从根节点开始向下跳,跳不动了就是答案。
代码:
#include<bits/stdc++.h>
#define N 100005
#define ll long long
using namespace std;
inline int read(){
int ans=0,w=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans*w;
}
int n,m,siz[N],first[N],lastrt,cnt,tot,sum,rt,vis[N],pa[N],Log[N<<2],fsiz[N];
ll d1[N],d2[N],sumv[N];
struct edge{int v,next,w;}e[N<<1];
inline void Add(int u,int v,int w){e[++cnt].v=v,e[cnt].next=first[u],e[cnt].w=w,first[u]=cnt;}
struct Tree{
int first[N],cnt,tot,st[N<<2][21],d[N],dfn[N];
edge t[N<<1];
inline int min(int a,int b){return a<b?a:b;}
inline void add(int u,int v,int w){t[++cnt].v=v,t[cnt].w=w,t[cnt].next=first[u],first[u]=cnt;}
inline int getdis(int u,int v){
if(dfn[u]>dfn[v])swap(u,v);
int tmp=Log[dfn[v]-dfn[u]+1];
return d[u]+d[v]-2*min(st[dfn[u]][tmp],st[dfn[v]-(1<<tmp)+1][tmp]);
}
inline void dfs(int p,int fa){
st[(dfn[p]=++tot)][0]=d[p];
for(int i=first[p];i;i=t[i].next){
int v=t[i].v;
if(v==fa)continue;
d[v]=d[p]+t[i].w;
dfs(v,p);
st[++tot][0]=d[p];
}
}
inline void init(){
dfs(1,0);
for(int i=1;(1<<i)<=tot;++i)
for(int j=1;(1<<i)+j-1<=tot&&j<=tot;++j)
st[j][i]=min(st[j][i-1],st[j+(1<<(i-1))][i-1]);
}
}T;
inline int max(int a,int b){return a>b?a:b;}
inline void getrt(int p,int fa){
siz[p]=1,fsiz[p]=0;
for(int i=T.first[p];i;i=T.t[i].next){
int v=T.t[i].v;
if(vis[v]||v==fa)continue;
getrt(v,p),siz[p]+=siz[v],fsiz[p]=max(fsiz[p],siz[v]);
}
fsiz[p]=max(fsiz[p],sum-siz[p]);
if(fsiz[p]<fsiz[rt])rt=p;
}
inline void solve(int p,int fa){
vis[p]=1,pa[p]=fa;
for(int i=T.first[p];i;i=T.t[i].next){
int v=T.t[i].v;
if(vis[v])continue;
fsiz[(rt=0)]=sum=siz[v],getrt(v,0),Add(p,rt,v);
solve(rt,p);
}
}
inline void update(int p,int val){
sumv[p]+=val;
for(int i=p;pa[i];i=pa[i]){
int dis=T.getdis(pa[i],p);
d1[pa[i]]+=(ll)dis*val,d2[i]+=(ll)dis*val,sumv[pa[i]]+=val;
}
}
inline ll calc(int p){
ll res=d1[p];
for(int i=p;pa[i];i=pa[i]){
int dis=T.getdis(pa[i],p);
res+=d1[pa[i]]-d2[i]+dis*(sumv[pa[i]]-sumv[i]);
}
return res;
}
inline ll query(int p){
ll ans=calc(p);
for(int i=first[p];i;i=e[i].next){
ll tmp=calc(e[i].w);
if(tmp<ans)return query(e[i].v);
}
return ans;
}
int main(){
Log[0]=-1,n=read(),m=read();
for(int i=1;i<n;++i){
int x=read(),y=read(),z=read();
T.add(x,y,z),T.add(y,x,z);
}
for(int i=1;i<(N<<2);++i)Log[i]=Log[i>>1]+1;
T.init(),sum=n,fsiz[(rt=0)]=n,getrt(1,0),lastrt=rt,solve(rt,0),rt=lastrt;
while(m--){
int x=read(),y=read();
update(x,y),cout<<query(rt)<<'\n';
}
return 0;
}
2018.08.28 洛谷P3345 [ZJOI2015]幻想乡战略游戏(点分树)的更多相关文章
- 洛谷 P3345 [ZJOI2015]幻想乡战略游戏 解题报告
P3345 [ZJOI2015]幻想乡战略游戏 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做 ...
- 洛谷P3345 [ZJOI2015]幻想乡战略游戏(动态点分治,树的重心,二分查找,Tarjan-LCA,树上差分)
洛谷题目传送门 动态点分治小白,光是因为思路不清晰就耗费了不知道多少时间去gang这题,所以还是来理理思路吧. 一个树\(T\)里面\(\sum\limits_{v\in T} D_vdist(u,v ...
- 洛谷P3345 [ZJOI2015]幻想乡战略游戏 [动态点分治]
传送门 调了两个小时,终于过了-- 凭啥人家代码80行我180行啊!!! 谁叫你大括号换行 谁叫你写缺省源 思路 显然,补给点所在的位置就是这棵树的带权重心. 考虑size已知时如何找重心:一开始设答 ...
- bzoj3924 [Zjoi2015]幻想乡战略游戏 点分树,动态点分
[BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...
- P3345 [ZJOI2015]幻想乡战略游戏
传送门 考虑先随便找一个点作为根,然后再慢慢移动根,这样一步步走到最优的点 设 $sum[x]$ 表示节点 $x$ 的子树的军队数,$len(x,y)$ 表示 $x,y$ 之间边的长度 那么对于根节点 ...
- P3345 [ZJOI2015]幻想乡战略游戏 动态点分治
\(\color{#0066ff}{ 题目描述 }\) 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越 ...
- BZOJ 3924 / Luogu P3345 [ZJOI2015]幻想乡战略游戏 (动态点分治/点分树)
题意 树的结构不变,每个点有点权,每一条边有边权,有修改点权的操作,设xxx为树中一点.求∑idist(x,i)∗a[i]\sum_idist(x,i)*a[i]i∑dist(x,i)∗a[i]的最 ...
- AC日记——[ZJOI2015]幻想乡战略游戏 洛谷 P3345
[ZJOI2015]幻想乡战略游戏 思路: 树剖暴力转移: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1 ...
- [ZJOI2015]幻想乡战略游戏——动态点分治
[ZJOI2015]幻想乡战略游戏 带修改下,边点都带权的重心 随着变动的过程中,一些子树内的点经过会经过一些公共边.考虑能不能对这样的子树一起统计. 把树上贡献分块. 考虑点分治算法 不妨先把题目简 ...
随机推荐
- web 复制功能和span光标
参考文章:https://www.cnblogs.com/tugenhua0707/p/7395966.html https://blog.csdn.net/woshinia/article/deta ...
- python 之九九乘法表
for i in range(1,10): for j in range(1,i+1): print(f"{j}*{i}={i*j}",end='\t') print() 运行结果 ...
- Window python下载安装
Window python下载安装 http://www.runoob.com/python/python-install.html https://pan.baidu.com/s/1MoR9nWUY ...
- 在eclipse中创建maven项目,亲测有效,详细步骤
一.想要使用maven,首先要配置本地maven的环境 1.在http://maven.apache.org/download.cgi中去下载maven 2. 3.下载完毕后将压缩包解压到自己记住的位 ...
- vue 引入bootstarp --webpack
注意对应好版本 - 稳定版本 :"bootstrap": "^3.0.0" 否则样式异常, 1.npm install jquery --save-dev 引 ...
- VBox 安装 macOS 10.12
安装步骤⑴ 下载及解压 macOS 10.12 Sierra Final by TechReviews.rar ⑵ 下载及双击安装 VirtualBox-5.1.6-110634-Win.exe ,默 ...
- 关于str.split(",")中间 什么时候该加\\转义
java 分割符,对于某些符号的分割符进行切割的时候需要加转义字符,我贴上例子 1. package test1; public class split { public static void ma ...
- ROC曲线和AUC值(转)
http://www.cnblogs.com/dlml/p/4403482.html 分类器性能指标之ROC曲线.AUC值 一 roc曲线 1.roc曲线:接收者操作特征(receiveroperat ...
- R语言做条形图时候,离散变量和连续型变量的区别
1)条形图 条形图或许是最常用图形,常用来展示分类(different categories on the x-axis)和数值(numeric values on the y-axis)之间的关系. ...
- JDK中rt.jar、tools.jar和dt.jar作用
dt.jar和tools.jar位于:{Java_Home}/lib/下,而rt.jar位于:{Java_Home}/jre/lib/下,其中: rt.jar是JAVA基础类库,也就是你在java d ...