【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]幻想乡战略游戏 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做 ...
随机推荐
- 论文翻译_Tracking The Untrackable_Learning To Track Multiple Cues with Long-Term Dependencies_IEEE2017
Tracking The Untrackable: Learning to Track Multiple Cues with Long-Term Dependencies 跟踪不可跟踪:学习跟踪具有长 ...
- Android之Activity小结
Acitivity: 四种状态:活动状态.暂停状态.停止状态.销毁状态 四种加载模式:standard ,singleTop,singleTask,singleInstance: 七大方法:onCre ...
- java设计模式之命令模式以及在java中作用
命令模式属于对象的行为模式.命令模式又称为行动(Action)模式或交易(Transaction)模式. 命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请 ...
- mysql 数据库 exists 和count
由于最近在使用exists是出现了一个小问题,但是在调试的时候费了不少时间,因为自己只是牢固造成,所以在在此记录,已提醒自己. mysql中exists 用法: 通过和主查询管理 以达到过滤的效果,如 ...
- 【Python】python中的装饰器——@
对装饰器本来就一知半解的,今天终于弄清楚了,Python中的装饰器是对装饰者模式的很好运用,简化到骨子里了. python中为什么需要装饰器,看这里:http://www.cnblogs.com/hu ...
- pta指针作业
#PTA实验作业 6-1 本题pta提交列表 设计思路 本题是一道简单的指针程序题,两个数已经分别被指针定义,只要把用其指针把二者加在一起和减去即可 调试过程 本题无调试过程 代码截图 6-2 1. ...
- delphi RGB与TColor的转换
1.RGB转换为Tcolor function RGBToColor(R,G,B: byte): Tcolor;begin Result := B Shl 16 or G shl 8 or R;e ...
- hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)
hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...
- 【BZOJ 4034】[HAOI2015]树上操作 差分+dfs序+树状数组
我们只要看出来这道题 数组表示的含义就是 某个点到根节点路径权值和就行 那么我们可以把最终答案 看做 k*x+b x就是其深度 ,我们发现dfs序之后,修改一个点是差分一个区间,修改一个点的子树,可以 ...
- 十个迅速提升JQuery性能的技巧
本文提供即刻提升你的脚本性能的十个步骤.不用担心,这并不是什么高深的技巧.人人皆可运用!这些技巧包括: 使用最新版本 合并.最小化脚本 用for替代each 用ID替代class选择器 给选择器指定前 ...