bzoj2959: 长跑(LCT+并查集)
题解
LCT常数大得真实
没有环,就是\(lct\)裸题吧
有环,我们就可以绕环转一圈,缩点
怎么搞?
当形成环时,把所有点的值全部加到一个点上,用并查集维护加到哪个点上
判断连通性再用一个并查集
Code
#include<bits/stdc++.h>
#define LL long long
#define RG register
using namespace std;
template<class T> inline void read(T &x) {
x = 0; RG char c = getchar(); bool f = 0;
while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
x = f ? -x : x;
return ;
}
template<class T> inline void write(T x) {
if (!x) {putchar(48);return ;}
if (x < 0) x = -x, putchar('-');
int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
}
const int N = 150010;
struct node {
int v, s, fa, ch[2];
bool rev;
}t[N];
int S[N], top;
#define lson (t[x].ch[0])
#define rson (t[x].ch[1])
void pushup(int x) {t[x].s = (t[lson].s + t[rson].s + t[x].v);return ;}
void putrev(int x) {
swap(lson, rson);
t[x].rev ^= 1;
return ;
}
void pushdown(int x) {
if (t[x].rev) {
if (lson) putrev(lson);
if (rson) putrev(rson);
t[x].rev = 0;
}
}
int fa[N], Fa[N];
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
int Find(int x) {
return Fa[x] == x ? x : Fa[x] = Find(Fa[x]);
}
bool isroot(int x) {
return (t[find(t[x].fa)].ch[0] != x) && (t[find(t[x].fa)].ch[1] != x);
}
void rotate(int x) {
int y = find(t[x].fa), z = find(t[y].fa), k = t[y].ch[1] == x;
if (!isroot(y)) t[z].ch[t[z].ch[1] == y] = x;
t[x].fa = z;
t[t[x].ch[k^1]].fa = y, t[y].ch[k] = t[x].ch[k^1];
t[x].ch[k^1] = y; t[y].fa = x;
pushup(y);
return ;
}
void splay(int x) {
S[top = 1] = x;
for (RG int i = x; !isroot(i); i = find(t[i].fa)) S[++top] = find(t[i].fa);
for (RG int i = top; i; i--) pushdown(S[i]);
while (!isroot(x)) {
int y = find(t[x].fa), z = find(t[y].fa);
if (!isroot(y))
(t[y].ch[1] == x) ^ (t[z].ch[1] == y) ? rotate(x) : rotate(y);
rotate(x);
}
pushup(x);
return ;
}
void access(int x) {
for (int y = 0; x; y = x, x = find(t[x].fa))
splay(x), t[x].ch[1] = y, pushup(x);
}
void makeroot(int x) {
access(x); splay(x); putrev(x);
return ;
}
void link(int x, int y) {
makeroot(x);
t[x].fa = y;
}
void split(int x, int y) {
makeroot(x), access(y), splay(y);
return ;
}
int a[N], n, m;
void dfs(int x, int y) {
fa[x] = y;
pushdown(x);
if (lson) dfs(lson, y);
if (rson) dfs(rson, y);
return ;
}
int main() {
read(n), read(m);
for (int i = 1; i <= n; i++) read(a[i]), fa[i] = Fa[i] = i, t[i].s = t[i].v = a[i];
while (m--) {
int x, y, op;
read(op), read(x), read(y);
if (op == 1) {
x = find(x), y = find(y);
if (x == y) continue;
if (Find(x) != Find(y)) {
link(x, y);
Fa[Find(y)] = Find(x);
}
else {
split(x, y);
t[y].v = t[y].s;
dfs(y, y);
t[y].ch[0] = 0;
}
}
else if (op == 2) {
int tx = find(x);
splay(tx);
t[tx].s += y - a[x];
t[tx].v += y - a[x];
a[x] = y;
}
else {
x = find(x), y = find(y);
if (Find(x) != Find(y)) {
puts("-1");
continue;
}
split(x, y);
printf("%d\n", t[y].s);
}
}
return 0;
}
bzoj2959: 长跑(LCT+并查集)的更多相关文章
- BZOJ2959长跑——LCT+并查集(LCT动态维护边双连通分量)
题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前. 为 ...
- bzoj2959: 长跑 LCT+并查集+边双联通
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2959 题解 调了半天,终于调完了. 显然题目要求是求出目前从 \(A\) 到 \(B\) 的可 ...
- 【bzoj2959】长跑 LCT+并查集
题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前.为了 ...
- BZOJ 2959 长跑 (LCT+并查集)
题面:BZOJ传送门 当成有向边做的发现过不去样例,改成无向边就忘了原来的思路.. 因为成环的点一定都能取到,我们把它们压成一个新点,权值为环上所有点的权值和 这样保证了图是一颗森林 每次询问转化为, ...
- 【bzoj4998】星球联盟 LCT+并查集
题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两个 ...
- 【BZOJ2959】长跑 (LCT+并查集)
Time Limit: 1000 ms Memory Limit: 256 MB Description 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室 ...
- bzoj 2959: 长跑【LCT+并查集】
如果没有环的话直接LCT 考虑有环怎么办,如果是静态的话就tarjan了,但是这里要动态的缩环 具体是link操作的时候看一下是否成环(两点已联通),成环的话就用并查集把这条链缩到一个点,把权值加给祖 ...
- bzoj4998 星球联盟 LCT + 并查集
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4998 题解 根据题意,就是要动态维护点双,求出一个点双的权值和. 所以这道题就是和 bzoj2 ...
- BZOJ4998星球联盟——LCT+并查集(LCT动态维护边双连通分量)
题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成 联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两 ...
随机推荐
- class Qstring has no member named to Ascii
人家修改了.真的没有toAscii了.不过可以用toLatin1或者qPrintable()
- 掌握所有IO口的外部中断
外部中断配置流程 1.初始化IO口工作在普通IO.上拉输入状态. 2.首先开IO口组中断(P0IE=1.P1IE=1.P2IE=1): 3.开组内对应的具体某IO口中断(P0IEN.P1IEN.P2I ...
- CodeForces 681D Gifts by the List (树上DFS)
题意:一个家庭聚会,每个人都想送出礼物,送礼规则是, 一个人,先看名单列表,发现第一个祖先 就会送给他礼物,然后就不送了,如果他没找到礼物 他会伤心的离开聚会!告诉你m个祖先关系, 和每个人想给谁送! ...
- linux系统学习(一)
查看linux版本信息:http://distrowatch.com/ linux根目录下系统文件夹的含义 /boot 该目录下默认存放的是linux的启动文件和内核,一般200M swap交换分区, ...
- HTTP Debugger Pro使用教程
相关链接:HTTP Debugger Pro安装教程 1.设置过滤器,只监控指定地址的数据 选择仅显示匹配的记录 输入监控地址 控件传输的数据 服务器返回的数据
- 在Lua中封装一个调试日志(附lua时间格式)
--自己封装一个Debug调试日志 Debug={} Info={} local function writeMsgToFile(filepath,msg) end function Debug.Lo ...
- BZOJ 3884 上帝与集合的正确用法(扩展欧拉定理)
Description 根据一些书上的记载,上帝的一次失败的创世经历是这样的: 第一天, 上帝创造了一个世界的基本元素,称做“元”. 第二天, 上帝创造了一个新的元素,称作“α”.“α”被定义为“ ...
- Window-document-javascript
一个浏览器窗口有一个window对象,javascript属于window对象,html为document对象,属于window,body为document对象,只有设置body对象高度为100%,其 ...
- Linq转换操作之ToArray,ToList,ToDictionary源码分析
Linq转换操作之ToArray,ToList,ToDictionary源码分析 一:linq中的转换运算符 1. ToArray 我们经常用在linq查询上吧. linq只能运用在IEnumerab ...
- ajax 解析
1.通过适当的Ajax应用达到更好的用户体验; 2.把以前的一些服务器负担的工作转嫁到客户端,利于客户端闲置的处理能力来处理,减轻服务器和带宽的负担,从而达到节约ISP的空间及带宽租用成本的目的. 二 ...