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

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

对于每个节点我们保存这个子树的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. 详说大数据计算的可类化Classable

    可类化(Classable)是Laxcus大数据管理系统提供的一项基础功能,它能够将类转化为一串字节数组,或者逆向将字节数组转化为一个类.这项功能与JAVA提供的序列化(Serializable)非常 ...

  2. Python——数据类型之set

    本篇主要内容 • set集合的特点 • set集合的建立 • set集合的17个内置函数 • set集合的数学运算符号 1.set集合类型的特点. 1.无序 2.不同元素 3.元素必须不可变.(数字, ...

  3. [C/C++] new/delete和malloc/free基本区别

    /**便于遗忘时复习**/ 区别一:本质 new/delete 在C++中是运算符不是函数,需要编译器支持.malloc/free是库函数,需要头文件支持,在C语言中使用. 区别二:开辟内存大小 用 ...

  4. Android 之Buletooth

    一:概要: Android提供了Buletooth的API ,通过API 我们可以进行如下的一些操作: 1.扫描其他的蓝牙设备 2.查询能配对的蓝牙设备 3.建立RFCOMM 通道 4.连接其他的蓝牙 ...

  5. tinymce4.x 上传本地图片 (转载)

    转载自:http://www.cnblogs.com/fhen/p/5809514.html tinymce4.x 上传本地图片   tinymce是一款挺不错的html文本编辑器.但是添加图片是直接 ...

  6. js保留两位小数,不四舍五入

    //不进行四舍五入,保留两位小数 function getKeepTwoDecimals(val) { var newVal = (parseInt(val * 100) / 100).toFixed ...

  7. 文件系统中 atime,lazytime,relatime 详聊

    atime,ctime,mtime是文件inode的三个时间戳,分别表示文件最近一次的访问时间:inode本身的更改(changed)时间:文件数据的更改(modify)时间:这几个概念还是很好区分. ...

  8. JavaScript内置对象常用

    Math 提供了数学中常用的属性和方法,使用时直接用Math.属性/方法,而不需要new一个Math对象 Date 使用Date对象来对日期和时间进行操作.使用时,必须用new创建一个实例 windo ...

  9. struts标签中的select

    <!-- Struts下拉列表标签: name="deptId" 下拉列表标签的名称(服务器根据这个名称获取选择的项的实际的值value值) headerKey 默认选择项的 ...

  10. P1140 相似基因

    题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了4种核苷酸,简记作A,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. 在一个人类基因工作组的任务中,生物学家研究 ...