解析

本题需要用LCT维护子树大小
然后我就不会了
然后我就用树剖水过去了
又快又好写,真香

现在详细聊聊如何用LCT维护子树信息
每个结点再定义一个新的变量记录所有虚儿子的信息
然后…完了?

告别盲目pushup,我们来详细聊聊在哪里需要更新虚儿子的信息

毋庸置疑,应该在虚儿子信息改变的时候(废话)
那么什么时候发生改变呢?

  1. access:虚实边会交换状态,需要更新虚子树状态
  2. link:增加了虚儿子,需要更新虚子树状态

没了
splay、rotate、makeroot、findroot都是在一个splay里自己玩泥巴,显然不会改变虚儿子的状态
注意cut是减少了一个实儿子,也没有改变虚儿子状态
似乎还不太难对吧
所以,对于LCT的标记问题,我们要理性分析,相信科学

update:

纸上得来终觉浅,绝知此事要躬行

(翻译:不要口胡)
qwq
不自己写一遍是真的找不到坑点…
这里的link改变虚子树状态的时候,会连带上面一串splay的信息都出问题!
而且由于其他地方默认的是原来的信息正确,因此这里即使后面splay或makeroot也于事无补
解决办法是把y转到根再更新其虚子树信息

inline void link(int x,int y){makeroot(x);access(y);splay(y);siz0[y]+=siz[x];f[x]=y;pushup(y);return;
}

代码

然而懒得重写,还是贴的我的树剖
明天晨练可以写遍这个

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5+100;
const int mod=1e9+7;
const double eps=1e-9;
inline ll read() {ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m;
struct node{int to,nxt;
}p[N<<1];
int fi[N],cnt;
inline void addline(int x,int y){p[++cnt]=(node){y,fi[x]};fi[x]=cnt;return;
}
struct ope{int op,x,y;
}q[N];
struct edge{int x,y;
}e[N];
int tot,fa[N],num[N];
int find(int x){return x==fa[x]?x:find(fa[x]);}
inline void merge(int x,int y){x=find(x);y=find(y);if(num[x]>num[y]) swap(x,y);e[++tot]=(edge){x,y};fa[x]=y;num[y]+=num[x];return;
}int dfn[N],pos[N],tim,f[N],siz[N],hson[N],top[N];
int pl[N][19];
void dfs1(int x,int fa){f[x]=fa;pl[x][0]=fa;for(int k=1;pl[x][k-1];k++) pl[x][k]=pl[pl[x][k-1]][k-1];siz[x]=1;for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(to==fa) continue;dfs1(to,x);siz[x]+=siz[to];if(siz[to]>siz[hson[x]]) hson[x]=to;}return;
}
void dfs2(int x,int tp){top[x]=tp;pos[x]=++tim;dfn[tim]=x;if(hson[x]) dfs2(hson[x],tp);for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(to==f[x]||to==hson[x]) continue;dfs2(to,to);}return;
}int val[N];
inline void add(int p,int w){for(;p<=n;p+=p&-p) val[p]+=w;return;
}
inline int ask(int p){int res(0);for(;p;p-=p&-p)   res+=val[p];return res;
}
void init(){for(int i=1;i<=n;i++){add(pos[i],siz[i]);add(pos[i]+1,-siz[i]);}return;
}void upd(int x,int anc,int w){while(top[x]!=top[anc]){add(pos[top[x]],w);add(pos[x]+1,-w);x=f[top[x]];}add(pos[anc],w);add(pos[x]+1,-w);return;
}ll ans[N];
int o;
int main() {#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifmemset(fi,-1,sizeof(fi));cnt=-1;n=read();m=read();for(int i=1;i<=n;i++) num[i]=1,fa[i]=i;for(int i=1;i<=m;i++){char c;int x,y;scanf(" %c",&c);x=read(),y=read();q[i]=(ope){c=='A',x,y};if(c=='A'){addline(x,y);addline(y,x);merge(x,y);}}for(int i=1;i<=n;i++){if(!siz[i]){dfs1(i,0);dfs2(i,i);}}init();for(int i=m;i>=1;i--){if(q[i].op){int x=e[tot].x,y=e[tot].y;--tot;num[y]-=num[x];fa[x]=x;x=q[i].x,y=q[i].y; if(f[x]==y) swap(x,y);int w=ask(pos[y]);int tp=x,oo=find(x);for(int k=17;k>=0;k--){if(!pl[tp][k]||find(pl[tp][k])!=oo) continue;tp=pl[tp][k];}upd(x,tp,-w);//printf("cut:(%d %d) w=%d tp=%d\n\n",x,y,w,tp);}else{int x=q[i].x,y=q[i].y;if(f[x]==y) swap(x,y);int sum=num[find(x)],bot=ask(pos[y]);ans[++o]=1ll*bot*(sum-bot);//printf("(%d %d):sum=%d bot=%d\n\n",x,y,sum,bot);}}while(o) printf("%lld\n",ans[o--]);return 0;
}
/*
8 12
A 2 3
Q 2 3
A 3 4
Q 2 3
A 3 8
Q 3 8
Q 3 4
Q 2 3
A 8 7
A 6 5
Q 8 7
Q 5 6*/

洛谷P4219 大融合(LCT、虚子树)相关推荐

  1. BZOJ 4530 大融合 LCT维护子树信息

    题意: N<=1e5个点,Q<=1e5个操作. 支持加一条边(u,v)(保证图是森林).询问经过边(u,v)的简单路径条数(保证(u,v)存在). 分析: 数据结构学傻了的我,表示并不会用 ...

  2. bzoj 4530 [Bjoi2014]大融合——LCT维护子树信息

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530 LCT维护子树 siz .设 sm[ ] 表示轻儿子的 siz 和+1(1是自己的si ...

  3. [BZOJ4530][Bjoi2014]大融合 LCT + 启发式合并

    [BZOJ4530][Bjoi2014]大融合 试题描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是 ...

  4. [lct] Luogu P4219 大融合

    题目描述 小强要在NN个孤立的星球上建立起一套通信系统.这套通信系统就是连接NN个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是它所在的当前能够 联通的树上路过它的简单路径 ...

  5. 洛谷P2495 [SDOI2011]消耗战(虚树dp)

    P2495 [SDOI2011]消耗战 题目链接 题解: 虚树\(dp\)入门题吧.虚树的核心思想其实就是每次只保留关键点,因为关键点的dfs序的相对大小顺序和原来的树中结点dfs序的相对大小顺序都是 ...

  6. 洛谷 P2486 [SDOI2011]染色 LCT

    Code: #include <cstdio> //SDOI2010 染色 #include <algorithm> #include <cstring> #inc ...

  7. 洛谷 P2829 大逃离 题解

    题目链接 一道模板的次短路 设 d i s [ x ] , d i s t [ x ] dis[x],dist[x] dis[x],dist[x] 分别为点 1 1 1 到 x x x 的最短路和次短 ...

  8. 洛谷P4338 [ZJOI2018]历史(LCT,树形DP,树链剖分)

    洛谷题目传送门 ZJOI的考场上最弱外省选手T2 10分成功滚粗...... 首先要想到30分的结论 说实话Day1前几天刚刚刚掉了SDOI2017的树点涂色,考场上也想到了这一点 想到了又有什么用? ...

  9. 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释...

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

最新文章

  1. 张钹、朱松纯、黄铁军等同台激辩:人工智能的“能”与“不能”
  2. Git 推送到远程仓库
  3. 免焊vga3加6接线图_计数器和接近开关两线怎么接,计数器接近开关接线图
  4. 【TensorRT】将 PyTorch 转化为可部署的 TensorRT
  5. em算法python代码_EM算法的python实现的方法步骤
  6. kafka 日志相关配置
  7. android自动生成cardview,学习使用Material Design控件(三)使用CardView实现卡片效果...
  8. iOS 移动端overflow:auto 滚动不平滑及bug处理
  9. JS使用闭包保护变量,防止污染
  10. Requests上传文件
  11. linux中查找文件并合并文件
  12. 優利系統眾裡尋“她”
  13. Qt OpenGL教程 (非常详细)
  14. Matlab数学建模学习报告(一)
  15. 二维离散沃尔什变换及matlab实现
  16. [新手教程]如何使用 AirDrop 发送文件
  17. 华硕笔记本进入pe系统-华硕电脑从U盘启动-实测有效-转载--记录用
  18. Win10安装WSL-Ubuntu18.04
  19. php钓鱼怎么使用方法,盘钩使用方法
  20. python做马尔科夫模型预测法_python实现隐马尔科夫模型HMM

热门文章

  1. “一边熬夜一边求不要猝死”,90后养生朋克指南,条条扎心!
  2. colorkey唇釉是否安全_colorkey空气唇釉,19/支
  3. java监听网络连接_Android RxJava 之网络链接监听示范
  4. python跟java 效率_Python和Java该如何选择?老男孩Python人工智能
  5. oracle天数加个随机数,如何给一个表某列加上指定的随机数
  6. 81. 搜索旋转排序数组 II(014)二分查找+思路+详解+二种做法
  7. C++ 学习之旅(4)——调试Debug
  8. linux可疑程序,linux可疑程序追踪
  9. [C++STL]C++实现stack容器适配器
  10. C++ class实现双亲表示法