BZOJ 3924: [Zjoi2015]幻想乡战略游戏(动态点分治)
这种动态点分治嘛,GDKOI时听打到了,也有同学讲到了,所以印象比较深刻也就想出来了,然后就在实现方面卡了好久= =
不得不说CLJ说得真的太简单了,实现方面根本没提。
首先我们可以先用树分治构建出这棵树的分治树,也就是把这棵树的重心作为根节点然后子树为他的子树的重心这样递归下去,然后每个节点存的是其子树的信息。
对于每个节点我们保存这个子树的dv的总和已经把该节点作为点的答案值
这样对于修改能在log n的时间内解决
寻找答案的时候,我们可以发现,如果现在节点的子树dv和*2大于总节点,那么向那个方向过去一定比原方案好
我们先从根节点开始,若发现答案在某棵子树时,我们考虑如何使其儿子节点的答案转变为整个树的答案,可以发现把除这个子树外的所有节点可以缩成一个节点并连在这棵子树上,然后就可以一直这样做下去,找到操作之后再把这些撤销
因此还是得维护一些奇奇怪怪的东西,但打出来还是挺短的
Code:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 100100
typedef long long ll;
typedef pair<ll,ll> ii;
typedef pair<ll,ii> iii;
#define fi first
#define se second
#define pb push_back
struct edges{int to,next,dist;}edge[maxn*];
int l,next[maxn];
inline void addedge(int x,int y,int z) {
edge[++l]=(edges){y,next[x],z};next[x]=l;
edge[++l]=(edges){x,next[y],z};next[y]=l;
}
bool done[maxn];
int s[maxn],f[maxn],root,size;
void dfs(int u,int fa){
s[u]=;f[u]=;
int v=;
for (int i=next[u];i;i=edge[i].next) {
if (done[v=edge[i].to]||v==fa) continue;
dfs(v,u);
s[u]+=s[v];
f[u]=max(f[u],s[v]);
}
f[u]=max(f[u],size-s[u]);
if (f[u]<f[root]) root=u;
}
vector<ii> pre[maxn];
void getdist(int u,int fa,int tar,int dist) {
pre[u].pb(ii(tar,dist));
s[u]=;int v=;
for (int i=next[u];i;i=edge[i].next) {
if (done[v=edge[i].to]||v==fa) continue;
getdist(v,u,tar,dist+edge[i].dist);
s[u]+=s[v];
}
}
vector<iii> ch[maxn];
void work(int u){
done[u]=;
int v=;
pre[u].pb(ii(u,));
for (int i=next[u];i;i=edge[i].next) {
if (done[v=edge[i].to]) continue;
getdist(v,,u,edge[i].dist);
f[]=size=s[v];
dfs(v,root=);
ch[u].pb(iii(root,ii(v,edge[i].dist)));
work(root);
}
}
ll cnt[maxn],sum[maxn];
vector<ll> sumdist[maxn];
inline void update(int x,ll y,ll z){
for (int i=;i<pre[x].size();i++) {
int u=pre[x][i].fi;
cnt[u]+=y;sum[u]+=z+y*pre[x][i].se;
if (i!=pre[x].size()-) {
int j=;
for (;j<ch[u].size();j++)
if (ch[u][j].fi==pre[x][i+].fi) sumdist[u][j]+=z+y*pre[x][i].se;
}
}
}
int realroot;
vector<iii> record;
inline ll query(){
int x=realroot;
int mx=;
record.clear();
while (x){
mx=;
for (int i=;i<ch[x].size();i++)
if (cnt[ch[x][mx].fi]<cnt[ch[x][i].fi]) mx=i;
if (ch[x].size()==||cnt[ch[x][mx].fi]*<=cnt[x]) {
ll ans=sum[x];
for (int i=;i<record.size();i++)
update(record[i].fi,record[i].se.fi,record[i].se.se);
return ans;
}
int v=ch[x][mx].fi;
record.pb(iii(ch[x][mx].se.fi,ii(-(cnt[x]-cnt[v]),
-(sum[x]-sumdist[x][mx]+(cnt[x]-cnt[v])*ch[x][mx].se.se))));
update(ch[x][mx].se.fi,cnt[x]-cnt[v],
sum[x]-sumdist[x][mx]+(cnt[x]-cnt[v])*ch[x][mx].se.se);
x=v;
}
}
int main(){
int n,Q;
scanf("%d%d",&n,&Q);
for (int i=;i<n;i++) {
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,z);
}
f[]=size=n;
dfs(,root=);
realroot=root;
work(root);
for (int i=;i<=n;i++) sumdist[i]=vector<ll>(ch[i].size(),);
while (Q--) {
int x,y;
scanf("%d%d",&x,&y);
update(x,y,);
printf("%lld\n",query());
}
return ;
}
BZOJ 3924: [Zjoi2015]幻想乡战略游戏(动态点分治)的更多相关文章
- bzoj 3924 [Zjoi2015]幻想乡战略游戏——动态点分治(暴力移动找重心)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3924 度数只有20,所以从一个点暴力枚举其出边,就能知道往哪个方向走. 知道方向之后直接走到 ...
- [ZJOI2015]幻想乡战略游戏——动态点分治
[ZJOI2015]幻想乡战略游戏 带修改下,边点都带权的重心 随着变动的过程中,一些子树内的点经过会经过一些公共边.考虑能不能对这样的子树一起统计. 把树上贡献分块. 考虑点分治算法 不妨先把题目简 ...
- 【BZOJ3924】[Zjoi2015]幻想乡战略游戏 动态树分治
[BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...
- [BZOJ3924][ZJOI2015]幻想乡战略游戏(动态点分治)
题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和别人打 ...
- P3345 [ZJOI2015]幻想乡战略游戏 动态点分治
\(\color{#0066ff}{ 题目描述 }\) 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越 ...
- 【bzoj3924】[Zjoi2015]幻想乡战略游戏 动态点分治
题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和别人打 ...
- ZJOI2015 幻想乡战略游戏 动态点分治_树链剖分_未调完
Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来, ...
- BZOJ 3924 / Luogu P3345 [ZJOI2015]幻想乡战略游戏 (动态点分治/点分树)
题意 树的结构不变,每个点有点权,每一条边有边权,有修改点权的操作,设xxx为树中一点.求∑idist(x,i)∗a[i]\sum_idist(x,i)*a[i]i∑dist(x,i)∗a[i]的最 ...
- bzoj 3924: [Zjoi2015]幻想乡战略游戏
Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来, ...
随机推荐
- SpringBoot JPA实现增删改查、分页、排序、事务操作等功能
今天给大家介绍一下SpringBoot中JPA的一些常用操作,例如:增删改查.分页.排序.事务操作等功能.下面先来介绍一下JPA中一些常用的查询操作: //And --- 等价于 SQL 中的 and ...
- JAVA-Unit01: 数据库原理 、 SQL(DDL、DML)
Unit01: 数据库原理 . SQL(DDL.DML) SQL语句是不区分大小写的,但是行业里习惯将关键字与分关键字用大小写岔开以提高可读性. SELECT SYSDATE FROM dual DD ...
- 解析xml的问题未解决
工作上需要解析xml,目前的逻辑是:解析xml到对象中,然后对象再插入数据库.但这存在内存溢出的风险. 今天做的另外一件事是将循环用到工作上,暂时还没有测试,是否能保证程序的重启.有待观察 ##### ...
- Python装饰器学习(九步入门)
这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 ? 1 2 3 4 5 6 7 8 # -*- coding:gbk -*- '''示 ...
- XML解析之SAX解析技术案例
Java代码: package com.xushouwei.xml; import java.io.File; import java.io.IOException; import java.text ...
- MySQL要导出成excel的方法
MySQL 要导出成 excel 文件很简单,执行类似这样的命令: select * from 某个表 into outfile 'd:/文件名.xls'; 上述命令你在服务器上执行,就导在 ...
- 2.13. 获取托管对象(Core Data 应用程序实践指南)
用NSFetchRequest获取NSArray,里面都是托管对象.如果上下文里没有数据,就会从持久化存储区里获取. NSFetchRequest *request = [NSFetchRequest ...
- C语言的指针使用
今天老师总结了一下指针内容,感觉对理解指针有帮助, 1.大家在使用指针的时候容易忽略掉指针所在的位置. 假如定义一个变量int a=10: int *p: p=&a; //p中存放变量 ...
- js架构设计模式——前端MVVM框架设计及实现(一)
前端MVVM框架设计及实现(一) 最近抽出点时间想弄个dom模块化的模板引擎,不过现在这种都是MVVM自带的,索性就想自己造轮子写一个简单的MVVM框架了 借鉴的自然还是从正美的avalon开始了,我 ...
- Storm InvalidTopologyException: null
异常信息: backtype.storm.generated.InvalidTopologyException: null at backtype.storm.daemon.common$valida ...