这题可以用线段树做,不过正解恐怕是动态点分治?(点分树)

简单介绍下动态点分治的概念:在点分治的过程中,一般我们面对的问题都是静态的。如果涉及到修改这类的操作,我们就希望找到我们是如何处理到当前的修改点的,换而言之,我们希望记录下点分治的过程,这样可以通过爬点分树等操作消除影响。

对于每个节点我们保存这个子树的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】幻想乡战略游戏的更多相关文章

  1. 【BZOJ3924】幻想乡战略游戏(动态点分治)

    [BZOJ3924]幻想乡战略游戏(动态点分治) 题面 权限题...(穷死我了) 洛谷 题解 考虑不修改 发现一个贪心的做法 假设当前放在当前位置 如果它有一个子树的兵的总数大于总数的一半 那么,放到 ...

  2. BZOJ3924 ZJOI2015 幻想乡战略游戏 【动态点分治】

    BZOJ3924 ZJOI2015 幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂 ...

  3. bzoj3924 [Zjoi2015]幻想乡战略游戏 点分树,动态点分

    [BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...

  4. BZOJ3924 [Zjoi2015]幻想乡战略游戏

    Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来, ...

  5. [BZOJ3924][ZJOI2015]幻想乡战略游戏(动态点分治)

    题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和别人打 ...

  6. BZOJ3924——[Zjoi2015]幻想乡战略游戏

    0.题意:动态维护带权中心 1.分析:妈的,这题做了一天,mdzzzzzzzzzzzzzzzzzz-.. 这个题是边权,我们首先要将边权转化成点权... 我们维护一个分支结构中到根的距离和,一个分支结 ...

  7. 【BZOJ3924】[Zjoi2015]幻想乡战略游戏 动态树分治

    [BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...

  8. LOJ2135 「ZJOI2015」幻想乡战略游戏

    题意 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和 ...

  9. LOJ #2135. 「ZJOI2015」幻想乡战略游戏

    #2135. 「ZJOI2015」幻想乡战略游戏 链接 分析: 动态点分治,求加权重心,带修改. 考虑如果知道了一个点s,如何求答案,那么首先可以点分治的思想,求每个联通块内所有点到分治中心距离和,然 ...

  10. 洛谷 P3345 [ZJOI2015]幻想乡战略游戏 解题报告

    P3345 [ZJOI2015]幻想乡战略游戏 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做 ...

随机推荐

  1. LeetCode 4——两个排序数组中的中位数

    1. 题目 2. 解答 2.1. 方法一 由于两个数组都是排好序的,因此首先可以想到的思路就是利用归并排序把两个数组合并成一个有序的长数组,然后直接取出中位数即可. class Solution: d ...

  2. hibernate 批量插入

    Session session = sessionFactoryUpLowLimit.openSession(); session.beginTransaction(); for(int i=0 ;i ...

  3. HDU 3269 P2P File Sharing System(模拟)(2009 Asia Ningbo Regional Contest)

    Problem Description Peer-to-peer(P2P) computing technology has been widely used on the Internet to e ...

  4. 团队项目-第十次scrum 会议

    时间:11.6 时长:20分钟 地点:主235教室走廊 工作情况 团队成员 已完成任务 待完成任务 解小锐 完成多种招聘方式的逻辑编写 陈鑫 实现游戏的存档功能 李金奇 添加多种招聘方式等功能 王辰昱 ...

  5. asp.net应用程序脱机app_offline.htm文件

    This application is currently offline. To enable the application, remove the app_offline.htm file fr ...

  6. Redis使用手册

    简介 Redis 是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型. Key-Value数据库. Redis面向互联网的方案提供了三种形式: 1.主从 主机进行写操作, ...

  7. jsp中的session和上下文

    Session的典型应用: 防止用户非法登录到某个页面. 网上商城的购物车 保存用户登录信息 注:多个请求要用的东西放在session中,多个会话之间要用的东西放在上下文中. 如何创建session? ...

  8. 【bzoj3000】Big Number 数论

    题目描述 给你两个整数N和K,要求你输出N!的K进制的位数. 输入 有多组输入数据,每组输入数据各一行,每行两个数——N,K 输出 每行一个数为输出结果. 样例输入 2 5 2 10 10 10 10 ...

  9. text-overflow使用文字超多div的宽度或超过在table中<td>

    关键字:text-overflow:ellipsis 语法:text-overflow:clip | ellipsis 取值 clip:默认值.不显示省略标记(...),而是简单的裁切. ellips ...

  10. Codeforce 721C DP+DAG拓扑序

    题意 在一个DAG上,从顶点1走到顶点n,路径上需要消费时间,求在限定时间内从1到n经过城市最多的一条路径 我的做法和题解差不多,不过最近可能看primer看多了,写得比较复杂和结构化 自己做了一些小 ...