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)判上下,超简便维护
但如果如图 :
兜来兜去的图发现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;
}
bzoj 3924 幻想乡战略游戏的更多相关文章
- bzoj 3924 幻想乡战略游戏 —— 动态点分治
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3924 参考了博客:https://blog.csdn.net/qq_34564984/art ...
- bzoj3924 [Zjoi2015]幻想乡战略游戏 点分树,动态点分
[BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...
- 【BZOJ3924】幻想乡战略游戏(动态点分治)
[BZOJ3924]幻想乡战略游戏(动态点分治) 题面 权限题...(穷死我了) 洛谷 题解 考虑不修改 发现一个贪心的做法 假设当前放在当前位置 如果它有一个子树的兵的总数大于总数的一半 那么,放到 ...
- LOJ2135 「ZJOI2015」幻想乡战略游戏
题意 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和 ...
- LOJ #2135. 「ZJOI2015」幻想乡战略游戏
#2135. 「ZJOI2015」幻想乡战略游戏 链接 分析: 动态点分治,求加权重心,带修改. 考虑如果知道了一个点s,如何求答案,那么首先可以点分治的思想,求每个联通块内所有点到分治中心距离和,然 ...
- 洛谷 P3345 [ZJOI2015]幻想乡战略游戏 解题报告
P3345 [ZJOI2015]幻想乡战略游戏 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做 ...
- [ZJOI2015]幻想乡战略游戏——动态点分治
[ZJOI2015]幻想乡战略游戏 带修改下,边点都带权的重心 随着变动的过程中,一些子树内的点经过会经过一些公共边.考虑能不能对这样的子树一起统计. 把树上贡献分块. 考虑点分治算法 不妨先把题目简 ...
- BZOJ3924 ZJOI2015 幻想乡战略游戏 【动态点分治】
BZOJ3924 ZJOI2015 幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂 ...
- AC日记——[ZJOI2015]幻想乡战略游戏 洛谷 P3345
[ZJOI2015]幻想乡战略游戏 思路: 树剖暴力转移: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1 ...
随机推荐
- javaweb基础(5)_servlet原理
一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...
- java中异常处理机制 throw抛出自定义业务逻辑异常 throws继续抛出 catch捕获后会自动继续抛向调用方法
package com.swift; public class Exception_TestC { public static void main(String[] args) { /* * 第5题: ...
- 关于lua 5.3 服务端热更新流程
脚本的热更新的流程都大同小异, 第一步先保存旧代码的块的数据, 第二部加载新的代码块,第三步将旧代码块的局部和全局数据拷贝到新代码块的对应的 变量中. 在服务器热更新中,主要考虑热更的内容是什么, 一 ...
- 2d游戏中的射线与矩形检测碰撞
cc.exports.LineCollideRect(startLine,endLine,rect)--向量与矩形检测碰撞 --获取矩形的四个顶点位置 local p = {cc.p(rect.x,r ...
- mysql 5.7安装密码校验插件validate_password
在使用服务器插件之前,必须将它们加载到服务器中.MySQL支持在服务器启动和运行时加载插件.还可以在启动时控制加载插件的激活状态,并在运行时卸载它们.在加载插件时,可以从INFORMATION_SCH ...
- Re:从零开始的Linux之路(目录配置)
基于 Red Hat Enterprise Linux 7.5 或者 CentOS 7.4 FHS协议(Filesystem Hierarchy Standard)——文件系统层次化标准 该标准定义了 ...
- 为PHPcms扩展json采集
最近想用phpcms做个新闻类网站,做采集的时候发现没有json的选项,于是自己动手,增加了采集json选项. 由于有的网站并不是纯json传输,而是jsonp,因此我把json,jsonp数据都当做 ...
- java 的多态(2013-10-11-163 写的日志迁移
java 的多态性:(所谓多态--就是指一个引用(类型)在不同情况下的多种状态) 1.方法的多态: 重载(overload) 重写(覆盖 override) 2.对象的多态性:(本人 ...
- 同一条sql在mysql5.6和5.7版本遇到的问题。
之前用的是mysql 5.6版本,执行select * from table group by colunm 是可以出结果的, 但是切换的5.7版本,这条sql就报错, Expression #1 o ...
- Linux学习-RPM 软件管理程序: rpm
RPM 默认安装的路径 一般来说,RPM 类型的文件在安装的时候,会先去读取文件内记载的设定参数内容,然后将该数据用来比对 Linux 系统的环境,以找出是否有属性相依的软件尚未安装的问题. 若环境检 ...