P4219 [BJOI2014]大融合 LCT维护子树大小
\(\color{#0066ff}{ 题目描述 }\)
小强要在\(N\)个孤立的星球上建立起一套通信系统。这套通信系统就是连接\(N\)个点的一个树。 这个树的边是一条一条添加上去的。在某个时刻,一条边的负载就是它所在的当前能够 联通的树上路过它的简单路径的数量。

例如,在上图中,现在一共有了\(5\)条边。其中,\((3,8)\)这条边的负载是\(6\),因 为有六条简单路径\(2-3-8\),\(2-3-8-7\),\(3-8\),\(3-8-7\),\(4-3-8\),\(4-3-8-7\)路过了\((3,8)\)。
现在,你的任务就是随着边的添加,动态的回答小强对于某些边的负载的 询问。
\(\color{#0066ff}{输入格式}\)
第一行包含两个整数 \(N, Q\),表示星球的数量和操作的数量。星球从 \(1\) 开始编号。
接下来的 \(Q\) 行,每行是如下两种格式之一:
A x y表示在 \(x\)和 \(y\) 之间连一条边。保证之前 \(x\) 和 \(y\)是不联通的。Q x y表示询问 \((x,y)\) 这条边上的负载。保证 \(x\) 和 \(y\) 之间有一条边。
\(\color{#0066ff}{输出格式}\)
对每个查询操作,输出被查询的边的负载。
\(\color{#0066ff}{输入样例}\)
8 6
A 2 3
A 3 4
A 3 8
A 8 7
A 6 5
Q 3 8
\(\color{#0066ff}{输出样例}\)
6
\(\color{#0066ff}{数据范围与提示}\)
对于所有数据,\(1≤N,Q≤10^5\)
\(\color{#0066ff}{ 题解 }\)
众所周知,LCT是维护树链的强力数据结构
对于维护一个子树的信息,是不太好维护的
但是动态的连边删边又不得不用LCT
其实,LCT维护一个子树信息并没有那么难
显然本题要维护的是子树siz
我们记tot为子树大小,siz为虚子树大小之和(LCT虚实边)
我们考虑LCT的哪些函数会影响这些东西
首先,upd肯定是要改的,即
void upd() {
tot = siz + 1;
if(ch[0]) tot += ch[0]->tot;
if(ch[1]) tot += ch[1]->tot;
}
注意,左右孩子实际上是splay维护的一条链上的两个点
tot初始为自己的虚子树的和+自己大小1
如果有实儿子,统计总共的大小
接下来rot和splay,显然不会改变边的虚实,所以直接维护即可
然后是access,它会改变很多边的虚实,所以会产生影响
也好维护,让x的siz减掉即将变成实边的虚边的贡献,加上即将变为虚边的实边的贡献即可
makeroot, findroot都没有影响qwq
link,有影响, 因为连了一条虚边,只需加一下贡献即可,加完后upd一下
注意link的不光要makeroot(x),还要把y弄到根上去,这样y就没有祖先了,再加就不会影响了
#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int maxn = 1e5 + 100;
struct LCT {
protected:
struct node {
node *ch[2], *fa;
int siz, rev, tot;
node(int siz = 0, int rev = 0, int tot = 1): siz(siz), rev(rev), tot(tot) { ch[0] = ch[1] = fa = NULL; }
void trn() { std::swap(ch[0], ch[1]), rev ^= 1; }
void dwn() {
if(!rev) return;
if(ch[0]) ch[0]->trn();
if(ch[1]) ch[1]->trn();
rev = 0;
}
void upd() {
tot = siz + 1;
if(ch[0]) tot += ch[0]->tot;
if(ch[1]) tot += ch[1]->tot;
}
bool isr() { return fa->ch[1] == this; }
bool ntr() { return fa && (fa->ch[0] == this || fa->ch[1] == this); }
}pool[maxn];
void rot(node *x) {
node *y = x->fa, *z = y->fa;
bool k = x->isr(); node *w = x->ch[!k];
if(y->ntr()) z->ch[y->isr()] = x;
(x->ch[!k] = y)->ch[k] = w;
(y->fa = x)->fa = z;
if(w) w->fa = y;
y->upd(), x->upd();
}
void splay(node *o) {
static node *st[maxn];
int top;
st[top = 1] = o;
while(st[top]->ntr()) st[top + 1] = st[top]->fa, top++;
while(top) st[top--]->dwn();
while(o->ntr()) {
if(o->fa->ntr()) rot(o->isr() ^ o->fa->isr()? o : o->fa);
rot(o);
}
}
void access(node *x) {
for(node *y = NULL; x; x = (y = x)->fa) {
splay(x);
if(x->ch[1]) x->siz += x->ch[1]->tot;
x->ch[1] = y;
if(y) x->siz -= y->tot;
x->upd();
}
}
void makeroot(node *o) { access(o), splay(o), o->trn(); }
public:
void link(int l, int r) {
node *x = pool + l, *y = pool + r;
makeroot(x), access(y), splay(y);
(x->fa = y)->siz += x->tot;
y->upd();
}
int query(int l, int r) {
node *x = pool + l, *y = pool + r;
makeroot(x), access(y), splay(y);
return (x->siz + 1) * (y->siz + 1);
}
}s;
int n, m;
char getch() {
char ch;
while(!isalpha(ch = getchar()));
return ch;
}
int main() {
n = in(), m = in();
for(int i = 1; i <= m; i++) {
if(getch() == 'A') s.link(in(), in());
else printf("%d\n", s.query(in(), in()));
}
return 0;
}
P4219 [BJOI2014]大融合 LCT维护子树大小的更多相关文章
- 【bzoj4530】[Bjoi2014]大融合 LCT维护子树信息
题目描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是它所在的当前能够联通的树上路过它的简单路径的数量 ...
- bzoj 4530 [Bjoi2014]大融合——LCT维护子树信息
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530 LCT维护子树 siz .设 sm[ ] 表示轻儿子的 siz 和+1(1是自己的si ...
- BZOJ4530[Bjoi2014]大融合——LCT维护子树信息
题目描述 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是它所在的当前能够 联通的树上路过它的简单路径的数 ...
- [BJOI2014]大融合 LCT维护子树信息
Code: #include <cstdio> #include <algorithm> #include <cstring> #include <strin ...
- bzoj 4530 大融合 —— LCT维护子树信息
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530 用LCT维护子树 size,就是实边和虚边分开维护: 看博客:https://blog ...
- Loj 2230. 「BJOI2014」大融合 (LCT 维护子树信息)
链接:https://loj.ac/problem/2230 思路: 设立siz数组保存虚点信息,sum表示总信息 维护子树信息link操作和access操作需要进行一些改动 可参考博客:https: ...
- 大融合——LCT维护子树信息
题目 [题目描述] 小强要在 $N$ 个孤立的星球上建立起一套通信系统.这套通信系统就是连接 $N$ 个点的一个树.这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是它所在的当前能够联通的树 ...
- P4219 [BJOI2014]大融合(LCT)
P4219 [BJOI2014]大融合 对于每个询问$(u,v)$所求的是 ($u$的虚边子树大小+1)*($v$的虚边子树大小+1) 于是我们再开个$si[i]$数组表示$i$的虚边子树大小,维护一 ...
- 洛谷 P4219 [BJOI2014]大融合 解题报告
P4219 [BJOI2014]大融合 题目描述 小强要在\(N\)个孤立的星球上建立起一套通信系统.这套通信系统就是连接\(N\)个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的 ...
随机推荐
- Struts2中web.xml里面struts-cleanup作用
struts2.1.3之后的版本均不需要配置该过滤器 参考: struts-cleanup作用 升级到struts-2.3.14.3之后涉及的改动以及ActionContextCleanUp,Stru ...
- spring学习七
一: web.xml中常用配置元素? <servlet></servlet>: 在向servlet或JSP页面制定初始化参数或定制URL时,首先命名servlet或JSP页面. ...
- leetcode633
用开方的思想来解题. bool judgeSquareSum(int c) { int h = pow(c, 0.5); ; i <= h; i++) { ), 0.5); if (left - ...
- OpenGL 着色器 03
着色器(shader)是运行在GPU上小程序. 也是一种非常独立的程序,它们之间不能相互通信:它们之间唯一的沟通只有通过输入和输出. 着色器的开头总是要声明版本,接着是输入和输出变量,uniform和 ...
- DAY2-python数据类型、字符编码、文件处理
阅读目录 一.引子 二.数字 三.字符串 四.列表 五.元祖 六.字典 七.集合 八.数据类型总结 九.运算符 十.字符编码 十一.文件处理 一.引子 1 什么是数据? x=10,10是我们要存储的数 ...
- 环境变量,include搜索路径,lib库搜索路径
环境变量 系统环境变量 我们知道,我们经常要设置一些环境变量,系统环境变量我们非常容易理解.其实我们在windows中经常容易接触.其实环境变量是一个非常广泛的一个概念,它与web应用程序中的web. ...
- IE的haslayout
haslayout 是Windows Internet Explorer渲染引擎的一个内部组成部分.在InternetExplorer中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元 ...
- ViewPager的使用方法
首先是 导入jar包 下载地址:android-support-v4.jar 布局文件里添加viewPager布局 [html] view plaincopy <android.suppor ...
- JavaPersistenceWithMyBatis3笔记-第1章-001
一.介绍 1.项目结构 2.数据库结构 二.代码 1.Mapper package com.mybatis3.mappers; import java.util.List; import com.my ...
- Java进程与多线程+线程中的join、yield、wait等方法+synchronized同步锁使用
首先了解什么是多线程与进程 进程:是一个执行过程,动态的概念 --->会分配内存线程:是进程的一个单元,线程是系统最小的执行单元 详解: http://blog.csdn.net/luoweif ...