【bzoj3924&&luogu3345】幻想乡战略游戏
这题可以用线段树做,不过正解恐怕是动态点分治?(点分树)
简单介绍下动态点分治的概念:在点分治的过程中,一般我们面对的问题都是静态的。如果涉及到修改这类的操作,我们就希望找到我们是如何处理到当前的修改点的,换而言之,我们希望记录下点分治的过程,这样可以通过爬点分树等操作消除影响。
对于每个节点我们保存这个子树的dv的总和已经把该节点作为点的答案值
这样对于修改能在$O(logn)的时间内解决
简要看下题意:询问树的带权重心,加修改。
如果不加修改,找到树的重心就是一个树形dp的傻题。
寻找答案的时候,我们可以发现,如果现在节点的子树dv和*2大于总节点,那么向那个方向过去一定比原方案好。
考虑如何处理修改?
我们先从根节点开始,若发现答案在某棵子树时,我们考虑如何使其儿子节点的答案转变为整个树的答案,可以发现把除这个子树外的所有节点可以缩成一个节点并连在这棵子树上,然后就可以一直这样做下去,找到操作之后再把这些撤销。
下面是咸鱼给出的一些实现细节:
1.跟虚树一样(不知道的可以百度“世界树”),这也是要在第二棵树上对原树进行统计,所以一定千万小心不要弄混,我学到的办法是对原树进行封装,这样即使不小心访问错了他也会给你提示。
2.对树进行欧拉序遍历可以利用rmq在$O(1)$查询LCA,这点也是特别好懂的。(只会树剖的蒟蒻瑟瑟发抖)
代码总共113行,应该是可读性比较好的。
zyz的那个码风清奇根本不能看啊QAQ
应该是目前比较能看的点分树代码之一吧。
#include<bits/stdc++.h>
#define N 100010
typedef long long ll;
using namespace std;
int n,m,x,y,z,size[N],tot;
int head[N],sum,rt,f[N],vis[N],par[N],cnt,lg[N<<];
ll dis1[N],dis2[N],sumv[N];
struct Edge{int u,v,next,w;}G[*N];
void Addedge(int u,int v,int w){
G[++tot].u=u;G[tot].v=v;G[tot].w=w;G[tot].next=head[u];head[u]=tot;
}
struct Orinal_Tree{
int head[N],cnt,tot;
int st[N<<][],dis[N],tpos[N<<];
struct edge{int u,v,next,w;}E[*N];
inline void addedge(int u,int v,int w){
E[++tot].u=u;E[tot].v=v;E[tot].w=w;E[tot].next=head[u];head[u]=tot;
E[++tot].u=v;E[tot].v=u;E[tot].w=w;E[tot].next=head[v];head[v]=tot;
}
inline int getdis(int u,int v){
if(tpos[u]>tpos[v])swap(u,v);
int k=lg[tpos[v]-tpos[u]+];
return dis[u]+dis[v]-*min(st[tpos[u]][k],st[tpos[v]-(<<k)+][k]);
}
void dfs(int u,int fa){
st[++cnt][]=dis[u];tpos[u]=cnt;
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;if(v==fa)continue;
dis[v]=dis[u]+E[i].w;
dfs(v,u);
st[++cnt][]=dis[u];
}
}
inline void initrmq(){
memset(tpos,,sizeof(tpos));cnt=;tot=;dis[]=;
dfs(,);
for(int j=;(<<j)<=cnt;j++)
for(int i=;i+(<<j)-<=cnt&&i<=cnt;i++)
st[i][j]=min(st[i][j-],st[i+(<<(j-))][j-]);
}
}T;
void getroot(int u,int fa){
size[u]=;f[u]=;
for(int i=T.head[u];i;i=T.E[i].next){
int v=T.E[i].v;if(vis[v]||v==fa)continue;
getroot(v,u);size[u]+=size[v];
f[u]=max(f[u],size[v]);
}
f[u]=max(f[u],sum-size[u]);
if(f[u]<f[rt])rt=u;
}
void work(int u,int fa){
vis[u]=;par[u]=fa;//printf("%d\n",u);puts("!!!");
for(int i=T.head[u];i;i=T.E[i].next){
int v=T.E[i].v;if(vis[v])continue;
sum=size[v];f[]=size[v];rt=;
getroot(v,);Addedge(u,rt,v);
work(rt,u);
}
}
inline void ins(int u,int val){
sumv[u]+=val;
for(int i=u;par[i];i=par[i]){
int dist=T.getdis(par[i],u);
dis1[par[i]]+=(ll)dist*val;
dis2[i]+=(ll)dist*val;
sumv[par[i]]+=val;
}
}
inline ll calc(int u){
ll ans=dis1[u];
for(int i=u;par[i];i=par[i]){
int dist=T.getdis(par[i],u);
ans+=dis1[par[i]]-dis2[i];
ans+=dist*(sumv[par[i]]-sumv[i]);
}
return ans;
}
ll query(int u){
ll ans=calc(u);//printf("%lld\n",ans);
for(int i=head[u];i;i=G[i].next){
ll tmp=calc(G[i].w);
if(tmp<ans)return query(G[i].v);
}
return ans;
}
inline int read(){
int f=,x=;char ch;
do{ch=getchar();if(ch=='-')f=-;}while(ch<''||ch>'');
do{x=x*+ch-'';ch=getchar();}while(ch>=''&&ch<='');
return f*x;
}
void init(){
memset(dis1,,sizeof(dis1));
memset(dis2,,sizeof(dis2));
memset(sumv,,sizeof(sumv));
lg[]=-;
for (int i=;i<(N<<);i++)lg[i]=lg[i>>]+;
n=read();m=read();//printf("%d %d\n",n,m);
for (int i=;i<n;i++)
x=read(),y=read(),z=read(),T.addedge(x,y,z);
}
int main(){
init();T.initrmq();sum=n;f[]=n;
rt=;getroot(,);
int LastOrder=rt;work(rt,);rt=LastOrder;
//for(int i=1;i<=20;i++)//printf("%d ",T.head[i]);puts("");
for(int i=;i<=m;i++){
x=read();y=read();ins(x,y);
printf("%lld\n",query(rt));
}
return ;
}
【bzoj3924&&luogu3345】幻想乡战略游戏的更多相关文章
- 【BZOJ3924】幻想乡战略游戏(动态点分治)
[BZOJ3924]幻想乡战略游戏(动态点分治) 题面 权限题...(穷死我了) 洛谷 题解 考虑不修改 发现一个贪心的做法 假设当前放在当前位置 如果它有一个子树的兵的总数大于总数的一半 那么,放到 ...
- BZOJ3924 ZJOI2015 幻想乡战略游戏 【动态点分治】
BZOJ3924 ZJOI2015 幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂 ...
- bzoj3924 [Zjoi2015]幻想乡战略游戏 点分树,动态点分
[BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...
- BZOJ3924 [Zjoi2015]幻想乡战略游戏
Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来, ...
- [BZOJ3924][ZJOI2015]幻想乡战略游戏(动态点分治)
题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和别人打 ...
- BZOJ3924——[Zjoi2015]幻想乡战略游戏
0.题意:动态维护带权中心 1.分析:妈的,这题做了一天,mdzzzzzzzzzzzzzzzzzz-.. 这个题是边权,我们首先要将边权转化成点权... 我们维护一个分支结构中到根的距离和,一个分支结 ...
- 【BZOJ3924】[Zjoi2015]幻想乡战略游戏 动态树分治
[BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...
- LOJ2135 「ZJOI2015」幻想乡战略游戏
题意 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和 ...
- LOJ #2135. 「ZJOI2015」幻想乡战略游戏
#2135. 「ZJOI2015」幻想乡战略游戏 链接 分析: 动态点分治,求加权重心,带修改. 考虑如果知道了一个点s,如何求答案,那么首先可以点分治的思想,求每个联通块内所有点到分治中心距离和,然 ...
- 洛谷 P3345 [ZJOI2015]幻想乡战略游戏 解题报告
P3345 [ZJOI2015]幻想乡战略游戏 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做 ...
随机推荐
- 在 C/C++ 中使用 TensorFlow 预训练好的模型—— 直接调用 C++ 接口实现
现在的深度学习框架一般都是基于 Python 来实现,构建.训练.保存和调用模型都可以很容易地在 Python 下完成.但有时候,我们在实际应用这些模型的时候可能需要在其他编程语言下进行,本文将通过直 ...
- day-8 python自带库实现ID3决策树算法
前一天,我们基于sklearn科学库实现了ID3的决策树程序,本文将基于python自带库实现ID3决策树算法. 一.代码涉及基本知识 1. 为了绘图方便,引入了一个第三方treePlotter模块进 ...
- 扩展欧几里得 求ax+by == n的非负整数解个数
求解形如ax+by == n (a,b已知)的方程的非负整数解个数时,需要用到扩展欧几里得定理,先求出最小的x的值,然后通过处理剩下的区间长度即可得到答案. 放出模板: ll gcd(ll a, ll ...
- [leetcode-635-Design Log Storage System]
You are given several logs that each log contains a unique id and timestamp. Timestamp is a string t ...
- BZOJ 2597 剪刀石头布(最小费用最大流)(WC2007)
Description 在一些一对一游戏的比赛(如下棋.乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之为剪刀石头布情况.有的时候,无聊的人们会津津乐道 ...
- Camera2与TextureView使用
package com.intsig.bcrsdk.demo.Activity; import android.annotation.TargetApi; import android.app.Act ...
- 软工实践 - 第二十六次作业 Beta 冲刺(4/7)
队名:起床一起肝活队 组长博客:https://www.cnblogs.com/dawnduck/p/10124816.html 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过 ...
- Hadoop世界中的HelloWorld之WordCount具体分析
MapReduce 应用举例:单词计数 WorldCount可以说是MapReduce中的helloworld了,下面来看看hadoop中的例子worldcount对其进行的处理过程,也能对mapre ...
- 修改CodeSmith中的SchemaExplorer.MySQLSchemaProvider
修改C:\Program Files (x86)\CodeSmith\v6.5\Samples\Projects\CSharp\MySQLSchemaProvider\MySQLSchemaProvi ...
- lintcode-117-跳跃游戏 II
117-跳跃游戏 II 给出一个非负整数数组,你最初定位在数组的第一个位置. 数组中的每个元素代表你在那个位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 样例 给出数组 ...