显然资源集合处就是树的重心,这题需要动态维护树的重心。

每个连通块以重心为根,用link-cut tree维护每个点的子树大小以及子树内所有点到它的距离和。

合并两个连通块时,考虑启发式合并,暴力往大的树中添加叶子。

添加叶子时,需要将叶子到重心路径上所有点的子树大小+1,距离和则加上一个等差数列。

并且新的重心是可能是原来的重心或者原来重心到叶子路径上的第一个点,暴力即可。

时间复杂度$O(n\log^2n)$。

 

#include<cstdio>
#define N 40010
int n,m,i,x,y,ans;char op[5];
int g[N],v[N<<1],nxt[N<<1],ed,f[N],son[N][2],val[N],tag[N],sum[N],ts[N],td[N],size[N],tmp[N];
inline void swap(int&a,int&b){int c=a;a=b;b=c;}
inline bool isroot(int x){return !f[x]||son[f[x]][0]!=x&&son[f[x]][1]!=x;}
inline void add1(int x,int p){if(!x)return;val[x]+=p;tag[x]+=p;}
inline void add2(int x,int s,int d){if(!x)return;sum[x]+=s+size[son[x][1]]*d;ts[x]+=s;td[x]+=d;}
inline void pb(int x){
if(tag[x]){
add1(son[x][0],tag[x]);
add1(son[x][1],tag[x]);
tag[x]=0;
}
if(td[x]){
add2(son[x][0],ts[x]+(size[son[x][1]]+1)*td[x],td[x]);
add2(son[x][1],ts[x],td[x]);
ts[x]=td[x]=0;
}
}
inline void up(int x){size[x]=size[son[x][0]]+size[son[x][1]]+1;}
inline void rotate(int x){
int y=f[x],w=son[y][1]==x;
son[y][w]=son[x][w^1];
if(son[x][w^1])f[son[x][w^1]]=y;
if(f[y]){
int z=f[y];
if(son[z][0]==y)son[z][0]=x;else if(son[z][1]==y)son[z][1]=x;
}
f[x]=f[y];f[y]=x;son[x][w^1]=y;up(y);
}
inline void splay(int x){
int s=1,i=x,y;tmp[1]=i;
while(!isroot(i))tmp[++s]=i=f[i];
while(s)pb(tmp[s--]);
while(!isroot(x)){
y=f[x];
if(!isroot(y)){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
rotate(x);
}
up(x);
}
inline void access(int x){for(int y=0;x;y=x,x=f[x])splay(x),son[x][1]=y,up(x);}
inline int root(int x){access(x);splay(x);while(son[x][0])x=son[x][0];return x;}
inline void addleaf(int x,int y){
f[y]=x,son[y][0]=son[y][1]=val[y]=tag[y]=sum[y]=ts[y]=td[y]=0,size[y]=1;
x=root(x),access(y),splay(x),add1(x,1),add2(x,0,1);
for(y=son[x][1];son[y][0];y=son[y][0]);splay(y);
int vx=val[x],vy=val[y];
if(vy*2>vx){
val[y]=vx,val[x]-=vy;
sum[x]-=sum[y]+vy,sum[y]+=sum[x]+vx-vy;
access(y),splay(x),son[x][0]=y,son[x][1]=0;
}
}
void dfs(int x,int y){
addleaf(y,x);
for(int i=g[x];i;i=nxt[i])if(v[i]!=y)dfs(v[i],x);
}
inline void addedge(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
inline void link(int x,int y){
int X=root(x),Y=root(y);
ans-=sum[X]+sum[Y];
if(val[X]<val[Y])swap(x,y);
dfs(y,x),addedge(x,y),addedge(y,x);
ans+=sum[root(x)];
}
int main(){
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)val[i]=size[i]=1;
while(m--){
scanf("%s",op);
if(op[0]=='A')scanf("%d%d",&x,&y),link(x,y);
if(op[0]=='Q')printf("%d\n",ans);
}
return 0;
}

  

BZOJ2888 : 资源运输的更多相关文章

  1. BZOJ2888 资源运输(LCT启发式合并)

    这道题目太神啦! 我们考虑他的每一次合并操作,为了维护两棵树合并后树的重心,我们只好一个一个的把节点加进去.那么这样一来看上去似乎就是一次操作O(nlogn),但是我们拥有数据结构的合并利器--启发式 ...

  2. 【BZOJ-2888】资源运输 LCT + 启发式合并

    2888: 资源运输 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 63  Solved: 33[Submit][Status][Discuss] D ...

  3. BZOJ 2888 资源运输(启发式合并LCT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2888 [题目大意] 不断加边,问每个连通块的重心到其它点的距离和的和 [题解] 启发式 ...

  4. 一些$LCT$的瓜皮题目

    一些瓜皮 放几个比较优(she)秀(pi)的\(LCT\)题. 老惯例,每一题代码因为一些未知原因消失了(如果要的话私我好了,虽然会咕咕咕). 嘴巴\(AC\)真香! [SP16580] QTREE7 ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. 百度云BaaS体系揭秘,突破共识机制、单机计算和串行处理三大瓶颈

    区块链作为去中心化的技术机制拥有广泛的应用场景与市场潜能.自2017年爆发式增长后,区块链虽然已经进入平稳期,但仍然存在概念混淆.技术性能制约.智能合约制约.共识机制.网络建设等痛点.为了打破行业壁垒 ...

  7. 【海岛帝国系列赛】No.3 海岛帝国:运输资源

    海岛帝国:运输资源 [试题描述] YSF考虑到“药师傅”帝国现在资源极度不平均,于是,商讨启用南水北调工程.YZM为首席工程师.现在,YSF由于工作紧张,准备军用物资和民用物资.但他要时时关注运输工程 ...

  8. 【BZOJ-3573】米特运输 树形DP

    3573: [Hnoi2014]米特运输 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1023  Solved: 604[Submit][Statu ...

  9. 【bzoj3573】[HNOI2014]米特运输

    题目描述 米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为主要能源的D星上,这种米特能源的运输和储存一直是一个大问题.D星上有N个城市,我们将其顺序编号为1到N,1号城市为首都.这N个城 ...

随机推荐

  1. 流媒体技术学习笔记之(十四)FFmpeg进行笔记本摄像头+麦克风实现流媒体直播服务

    FFmpeg推送视频流,Nginx RTMP模块转发,VLC播放器播放,实现整个RTMP直播 查看本机电脑的设备 ffmpeg -list_devices true -f dshow -i dummy ...

  2. php设计模式之注册树模式

    什么是注册树模式?[全局共享和交换对象] 注册树模式当然也叫注册模式,注册器模式.注册树模式通过将对象实例注册到一棵全局的对象树上,需要的时候从对象树上采摘的模式设计方法.   这让我想起了小时候买糖 ...

  3. .NET面试题系列(三)排序算法

    冒泡排序 , , , , , 7, 2, 4 }; //外层循环控制排序趟数 ; i < arr.Length - ; i++) { //内层循环控制每一趟排序多少次 ; j < arr. ...

  4. Docker01 CentOS配置Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...

  5. Ubuntu接显示器问题

    1.Could not apply the stored configuration for monitors 解决办法:Ubuntu在开机进入桌面的时候,会调用gnome-setting-deamo ...

  6. 【Udacity并行计算课程笔记】- lesson 1 The GPU Programming Model

    一.传统的提高计算速度的方法 faster clocks (设置更快的时钟) more work over per clock cycle(每个时钟周期做更多的工作) more processors( ...

  7. git merge branch to master

    git checkout master git pull git merge testbranch git push

  8. 关于RestFul API 介绍与实践

    之前演示的PPT,直接看图...     •参考链接: •RESTful API 设计最佳实践 •RESTful API 设计指南 •SOAPwebserivce和RESTfulwebservice对 ...

  9. Python发送邮件:smtplib、sendmail

    本地Ubuntu 18.04,本地Python 3.6.5, 阿里云Ubuntu 16.04,阿里云Python 3.5.2, smtplib,sendmail 8.15.2, 今天,打算实现通过电子 ...

  10. 浅谈js设计模式之发布 — 订阅模式

    发布 — 订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在 JavaScript开发中,我们一般用事件模型来替代传统的发布 — ...