bzoj 3924 幻想乡战略游戏

题目大意:
有边权点权的树,动态修改点权
每次修改后求带权重心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)判上下,超简便维护
但如果如图 :
1086046-20170114231012463-1469030409.jpg
兜来兜去的图发现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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402301.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 系统应用编程——网络编程(基础篇)

一、网络体系结构 1、OSI模型和TCP/IP 模型 网络体系结构指的是网络的分层结构以及每层使用的协议的集合。其中最著名的就是OSI协议参考模型&#xff0c;他是基于国际标准化组织&#xff08;OSI&#xff09;的建议发展起来的。它分为7个层次&#xff1a;应用层、表示层、会话层…

C++中函数的默认参数

使用方法&#xff1a; &#xff08;1&#xff09;在函数声明或定义时&#xff0c;直接对参数赋值&#xff0c;该参数就是默认参数。&#xff08;2&#xff09;在函数调用时&#xff0c;省略部分或全部参数&#xff0c;这时就会使用默认参数进行代替。注意事项&#xff1a; &…

Linux 系统应用编程——网络编程(socket编程)

二、网络编程基础 1、套接字概述 套接字就是网络编程的ID。网络通信&#xff0c;归根到底还是进程间的通信&#xff08;不同计算机上的进程间的通信&#xff09;。在网络中&#xff0c;每一个节点&#xff08;计算机或路由器&#xff09;都有一个网络地址&#xff0c;也就是IP地…

php curl拉取远程图片

<?php $url "图片绝对地址/thumbnail.jpg"; $filename curl.jpg; getImg($url, $filename); /**通过curl方式获取制定的图片到本地* 完整的图片地址* 要存储的文件名*/ function getImg($url "", $filename "") {if(is_dir(basename($fi…

利用indent格式化源文件的脚本

脚本一&#xff1a;格式化指定目录下的源文件(*.h, *.cpp...) #!/bin/sh# 格式化某目录下所有*.h, *.c, *.cpp, *.hh文件, 并将文件换行符转换成Linux下的格式if [ $# -lt 1 ]; thenecho "Usage: $0 <dir>"exit 1elsedir$1fi# format a source file(*.c, *.h,…

Struts入门(三)深入Struts用法讲解

访问Servlet APIAction搜索顺序动态方法调用指定多个配置文件默认ActionStruts 后缀接收参数处理结果类型1.访问Servlet API 首先我们了解什么是Servlet API httpRequest、httpResponse、servletContext  3个api对应jsp面向对象&#xff1a;request、response、application …

Linux ALSA声卡驱动之四:Control设备的创建

声明&#xff1a;本博内容均由http://blog.csdn.net/droidphone原创&#xff0c;转载请注明出处&#xff0c;谢谢&#xff01; Control接口 Control接口主要让用户空间的应用程序&#xff08;alsa-lib&#xff09;可以访问和控制音频codec芯片中的多路开关&#xff0c;滑动控件…

jQuery 入门教程(5): 显示/隐藏内容

2019独角兽企业重金招聘Python工程师标准>>> jQuery的hide()和show()可以用来显示和隐藏内容。比如下面的例子&#xff1a;jQuery的hide()和show() 可以用来显示和隐藏内容。比如下面的例子&#xff1a; [html] view plain copy print ? <!doctype html> …

键盘键值表

键盘键值表 值 描述 0x1 鼠标左键 0x2 鼠标右键 0x3 CANCEL 键 0x4 鼠标中键 0x8 BACKSPACE 键 0x9 TAB 键 0xC CLEAR 键 0xD ENTER 键 0x10 SHIFT 键 0x11 CTRL 键 0x12 MENU 键 0x13 PAUSE 键 0x14 CAPS LOCK 键 0x1B ESC 键 0x20 SPACEBAR 键 0x21 PAGE UP 键 0x22 PAGE DOW…

Spring自动扫描配置及使用方法

2019独角兽企业重金招聘Python工程师标准>>> 首先&#xff0c;检查一下你lib下有没有 common-annotations.jar 这个jar包 没有的话要导入工程。 下一步配置spring的配置文件applicationContex.xml&#xff0c;加入命名空间 红色为需要添加的内容 <beans xmlns…

Linux下ln命令使用

n是linux中又一个非常重要命令&#xff0c;它的功能是为某一个文件在另外一个位置建立一个同步的链接.当我们需要在不同的目录&#xff0c;用到相同的文件时&#xff0c;我们不需要在每一个需要的目录下都放一个必须相同的文件&#xff0c;我们只要在某个固定的目录&#xff0c…

DPM 2012 SP1---安装并部署DPM 2012 SP1服务器

实验拓扑图&#xff1a;一、前提条件&#xff1a;需要在DPM2012 SP1服务器上完成以下操作&#xff1a;1.DPM服务器加入域&#xff08;使用域管理员登陆DPM2012 SP1服务器&#xff09;2.准备存储磁盘&#xff08;新添加一块硬盘&#xff09;3.关闭防火墙服务&#xff08;DPM服务…

Linux下test命令使用

test命令格式&#xff1a; [cpp] view plain copy test condition 通常&#xff0c;在if-then-else语句中&#xff0c;用[]代替&#xff0c;即[ condition ]。注意&#xff1a;方括号两边都要用空格。 1、数值比较 比 较 描 述 ---------------------------------------…

用Mysql网页式管理工具安全地访问数据库的方法

2019独角兽企业重金招聘Python工程师标准>>> 用Mysql网页式管理工具安全地访问数据库的方法 在使用通达OA系统时很多用户需要借助Mysql网页式管理工具进入后台数据库去查看数据&#xff0c;进行一些相应的操作。但是大多数时候用户安装完该工具后都是直接进入后台数…

Linux 下的DMA浅析

DMA是一种无需CPU的参与就可以让外设和系统内存之间进行双向数据传输的硬件机制。使用DMA可以使系统CPU从实际的I/O数据传输过程中摆脱出来&#xff0c;从而大大提高系统的吞吐率。DMA经常与硬件体系结构特别是外设的总线技术密切相关。 一、DMA控制器硬件结构 DMA允许外围设备…

从值栈中获取数据

使用struts2的标签ognl表达式获取值栈数据 <s:property value"ognl表达式"/> 一、获取字符串 示例 打印后台string变量的值 jsp页面 Java代码 二、获取对象 示例 打印user对象的userName与userPwd的值 jsp页面 java代码 三、获取list集合 Java代码 1.通过list[…

SQL 事务

事务的acid理解简介ACID&#xff0c;是指在可靠数据库管理系统&#xff08;DBMS&#xff09;中&#xff0c;事务(transaction)所应该具有的四个特性&#xff1a;原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isola…

网络协议复习

不同协议所属的层次如下图&#xff1a; IP IP地址一开始是分类编址&#xff0c;到了20世纪90年代更换为无分类编址。分类编址时IP地址共有五类ABCDE。对于ABC类地址&#xff0c;IP地址都可以划分为网络标识和主机标识。从一个IP地址中提取网络地址要用网络掩码和IP地址进行与运…

CSDN-markdown编辑器使用手册

Markdown手册欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也…