以1为根建树,令$D_{i}$为$i$子树内所有节点$d_{i}$之和

令$ans_{i}$为节点$i$的答案,令$fa$为$i$的父亲,则$ans_{i}=ans_{fa}+dis(i,fa)(D_{1}-2D_{i})$

节点$i\ne 1$是最大值的必要条件是其$2D_{i}>D_{1}$,否则一定有$ans_{i}\ge ans_{fa}$

换言之,我们只需要考虑$i=1$或$2D_{i}>D_{1}$的节点,根据$d_{i}$非负的性质,不难证明这是一条以1为端点的链

对于这条链上的节点$i\ne 1$,必然有$ans_{i}<ans_{fa}$,因此最终即求这条链最底部的节点

对其求dfs序,这个最底部的节点也是dfs序最大的节点,线段树维护$D_{i}$最大值二分即可

由于修改是链修改,需要使用树链剖分,复杂度为$o(n\log^{2}n)$,可以通过

另外还需要查询$x$答案,即$ans_{1}+\sum_{i为x祖先或i=x,i\ne 1}dis(i,fa)(D_{1}-2D_{i})$,同样用树链剖分维护即可

(关于其点分的做法复杂度并不正确,因为还需要枚举每一个点的度数来找到移动的节点)

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define ll long long
5 #define L (k<<1)
6 #define R (L+1)
7 #define mid (l+r>>1)
8 struct Edge{
9 int nex,to,len;
10 }edge[N<<1];
11 int E,n,m,x,y,z,D,head[N],fa[N],sz[N],dep[N],mx[N],dfn[N],idfn[N],top[N],tag[N<<2],f[N<<2];
12 ll ans,val[N<<2],sum[N<<2];
13 void add(int x,int y,int z){
14 edge[E].nex=head[x];
15 edge[E].to=y;
16 edge[E].len=z;
17 head[x]=E++;
18 }
19 void dfs1(int k,int f,int sh){
20 fa[k]=f;
21 sz[k]=1;
22 dep[k]=sh;
23 for(int i=head[k];i!=-1;i=edge[i].nex)
24 if (edge[i].to!=f){
25 dfs1(edge[i].to,k,sh+edge[i].len);
26 sz[k]+=sz[edge[i].to];
27 if (sz[mx[k]]<sz[edge[i].to])mx[k]=edge[i].to;
28 }
29 }
30 void dfs2(int k,int fa,int t){
31 dfn[k]=++dfn[0];
32 idfn[dfn[0]]=k;
33 top[k]=t;
34 if (mx[k])dfs2(mx[k],k,t);
35 for(int i=head[k];i!=-1;i=edge[i].nex)
36 if ((edge[i].to!=fa)&&(edge[i].to!=mx[k]))dfs2(edge[i].to,k,edge[i].to);
37 }
38 void up(int k){
39 f[k]=max(f[L],f[R]);
40 sum[k]=sum[L]+sum[R];
41 }
42 void upd(int k,int x){
43 tag[k]+=x;
44 f[k]+=x;
45 sum[k]+=x*val[k];
46 }
47 void down(int k){
48 upd(L,tag[k]);
49 upd(R,tag[k]);
50 tag[k]=0;
51 }
52 void build(int k,int l,int r){
53 if (l==r){
54 val[k]=dep[idfn[l]]-dep[fa[idfn[l]]];
55 return;
56 }
57 build(L,l,mid);
58 build(R,mid+1,r);
59 val[k]=val[L]+val[R];
60 }
61 void update(int k,int l,int r,int x,int y,int z){
62 if ((l>y)||(x>r))return;
63 if ((x<=l)&&(r<=y)){
64 upd(k,z);
65 return;
66 }
67 down(k);
68 update(L,l,mid,x,y,z);
69 update(R,mid+1,r,x,y,z);
70 up(k);
71 }
72 void update(int k,int x){
73 while (k){
74 update(1,1,n,dfn[top[k]],dfn[k],x);
75 k=fa[top[k]];
76 }
77 }
78 int find(int k,int l,int r){
79 if (l==r)return l;
80 down(k);
81 if (2*f[R]>D)return find(R,mid+1,r);
82 return find(L,l,mid);
83 }
84 ll query(int k,int l,int r,int x,int y){
85 if ((l>y)||(x>r))return 0;
86 if ((x<=l)&&(r<=y))return sum[k];
87 down(k);
88 return query(L,l,mid,x,y)+query(R,mid+1,r,x,y);
89 }
90 ll query(int k){
91 ll ans=0;
92 while (k){
93 ans+=query(1,1,n,dfn[top[k]],dfn[k]);
94 k=fa[top[k]];
95 }
96 return ans;
97 }
98 ll calc(int k){
99 return ans+1LL*D*dep[k]-2*query(k);
100 }
101 int main(){
102 scanf("%d%d",&n,&m);
103 memset(head,-1,sizeof(head));
104 for(int i=1;i<n;i++){
105 scanf("%d%d%d",&x,&y,&z);
106 add(x,y,z);
107 add(y,x,z);
108 }
109 dfs1(1,0,0);
110 dfs2(1,0,1);
111 build(1,1,n);
112 for(int i=1;i<=m;i++){
113 scanf("%d%d",&x,&y);
114 D+=y;
115 ans+=1LL*dep[x]*y;
116 update(x,y);
117 printf("%lld\n",calc(idfn[find(1,1,n)]));
118 }
119 }

[loj2135]幻想乡战略游戏的更多相关文章

  1. LOJ2135 「ZJOI2015」幻想乡战略游戏

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

  2. 【BZOJ3924】幻想乡战略游戏(动态点分治)

    [BZOJ3924]幻想乡战略游戏(动态点分治) 题面 权限题...(穷死我了) 洛谷 题解 考虑不修改 发现一个贪心的做法 假设当前放在当前位置 如果它有一个子树的兵的总数大于总数的一半 那么,放到 ...

  3. LOJ #2135. 「ZJOI2015」幻想乡战略游戏

    #2135. 「ZJOI2015」幻想乡战略游戏 链接 分析: 动态点分治,求加权重心,带修改. 考虑如果知道了一个点s,如何求答案,那么首先可以点分治的思想,求每个联通块内所有点到分治中心距离和,然 ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. js高阶

    1. 面向对象编程介绍 1.1 两大编程思想 --- 面向过程 --- 面向对象 1.2 面向过程编程 POP 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候在一 ...

  2. Electron+Vue+ElementUI开发环境搭建

    Node环境搭建 本文假定你完成了nodejs的环境基础搭建: 镜像配置(暂时只配置node包镜像源,部分包的二进制镜像源后续讨论).全局以及缓存路径配置,全局路径加入到了环境变量 $ node -v ...

  3. OpenGL思维导图

  4. 一时兴起,用python抓了一下美女图片。实现简单。附上实现代码,可以交流。

    """1.定义目标网址 网址2.数据定位 照片3.数据匹配 标签4.数据下载 下载"""import requestsfrom lxml i ...

  5. Dapr-服务调用

    前言 上一篇对Dapr进行了了解,并搭建了Dapr环境.接下来就对Dapr的各个构建块类型的了解.应用实际案例. 一.服务调用: 在许多具有多个需要相互通信的服务的环境中,都会面临着很多问题. 如: ...

  6. 【数据结构与算法Python版学习笔记】查找与排序——散列、散列函数、区块链

    散列 Hasing 前言 如果数据项之间是按照大小排好序的话,就可以利用二分查找来降低算法复杂度. 现在我们进一步来构造一个新的数据结构, 能使得查找算法的复杂度降到O(1), 这种概念称为" ...

  7. 改善深层神经网络-week1编程题(Initializaion)

    Initialization 如何选择初始化方式,不同的初始化会导致不同的结果 好的初始化方式: 加速梯度下降的收敛(Speed up the convergence of gradient desc ...

  8. Seata整合SpringBoot和Mybatis

    Seata整合SpringBoot和Mybatis 一.背景 二.实现功能 三.每个服务使用到的技术 1.账户服务 2.订单服务 四.服务实现 1.账户服务实现 1.引入jar包 2.项目配置 3.建 ...

  9. [调试笔记] 10.8模拟赛11 T4 甜圈

    这题正解线段树维护哈希,同机房神犇已经讲的很明白了.这里只说sbwzx在调试的时候犯的sb错误. 1.关于pushdown和update 众所周知,sbwzx一写带lazy的线段树,就必在pushdo ...

  10. 文献翻译|Design of True Random Number Generator Based on Multi-stage Feedback Ring Oscillator(基于多级反馈环形振荡器的真随机数发生器设计)

    基于多级反馈环形振荡器的真随机数发生器设计 摘要 真随机数生成器(trng)在加密系统中起着重要的作用.本文提出了一种在现场可编程门阵列(FPGA)上生成真随机数的新方法,该方法以 多级反馈环形振荡器 ...