BZOJ 4764: 弹飞大爷
4764: 弹飞大爷
Time Limit: 30 Sec Memory Limit: 256 MB
Submit: 4 Solved: 4
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
1 1 1
1 1
1 2
1 3
2 1 2
1 1
1 2
1 3
2 3 -1
1 1
1 2
1 3
2 2 233
1 1
1 2
1 3
2 2 -233
1 1
1 2
1 3
Sample Output
3
2
1
2
2
1
-1
-1
-1
3
1
2
3
1
2
HINT
Source
今天偶然看到了某童鞋的弹飞绵羊的分块做法,十分不爽,想法卡他,然后就有了这道题,反正我觉得原来的分块方法是绝望了。但是万万木有想到,这道题依然有非LCT做法,比如大爷的Split Treap做法等等。
作为此题的出题人之一,其实我只负责题面部分和代码,解法都是ZZ和LH想的,和我没有半毛钱关系。
考虑怎么继续沿用弹飞绵羊的LCT做法,发现可能产生环,很烦。但是可以通过把环上的一条断掉,使得其在LCT中仍然是一棵树,我们把这条被“隐藏”起来的边标记在该树的Root上。那么每次加入边的时候,现考虑一下是否会形成环,如果会,就按照上面的方法处理。然后还有断边操作,只需要考虑一下断掉这条边后,是否会使得Root上的隐藏边重新显现即可。
不爽的是,刚刚放到大视野上一个下午,std就被LincHpin和Claris踩了。开心的是,至少我数据应该没造错。
#include <bits/stdc++.h> const int mxn = ; int tag[mxn];
int rev[mxn];
int siz[mxn];
int fat[mxn];
int son[mxn][]; inline bool isRoot(int t)
{
int f = fat[t]; if (!f)
return true; if (son[f][] == t)
return false;
if (son[f][] == t)
return false; return true;
} inline void update(int t)
{
siz[t] = ; if (son[t][])
siz[t] += siz[son[t][]];
if (son[t][])
siz[t] += siz[son[t][]];
} inline void connect(int f, int t, int s)
{
if (t)
fat[t] = f;
if (f)
son[f][s] = t;
} inline void rotate(int t)
{
int f = fat[t];
int g = fat[f];
int s = son[f][] == t; connect(f, son[t][!s], s);
connect(t, f, !s); fat[t] = g;
if (g && son[g][] == f)
son[g][] = t;
if (g && son[g][] == f)
son[g][] = t; update(f);
update(t);
} inline void push(int t)
{
if (rev[t])
{
rev[t] = ; if (son[t][])
rev[son[t][]] ^= ;
if (son[t][])
rev[son[t][]] ^= ; std::swap(son[t][], son[t][]);
}
} inline void pushdown(int t)
{
static int stk[mxn], tot; stk[++tot] = t; while (!isRoot(t))
stk[++tot] = t = fat[t]; while (tot)push(stk[tot--]);
} inline void splay(int t)
{
pushdown(t); while (!isRoot(t))
{
int f = fat[t];
int g = fat[f]; if (isRoot(f))
rotate(t);
else
{
int a = f && son[f][] == t;
int b = g && son[g][] == f; if (a == b)
rotate(f), rotate(t);
else
rotate(t), rotate(t);
}
}
} inline void access(int t)
{
int q = t; for (int p = ; t; p = t, t = fat[t])
splay(t), son[t][] = p, update(t); splay(q);
} inline void makeRoot(int t)
{
access(t), rev[t] ^= ;
} inline void link(int t, int f)
{
makeRoot(t), fat[t] = f;
} inline void cut(int t)
{
access(t);
fat[son[t][]] = ;
son[t][] = ;
update(t);
} inline int find(int t)
{
access(t); int p = t; while (son[p][])
p = son[p][]; return p;
} inline void Link(int t, int f)
{
if (t == f)
{
tag[t] = f;
return;
} if (find(t) != find(f))
link(t, f);
else
makeRoot(t), tag[t] = f;
} inline void change(int t, int f)
{
access(t); int p = find(t); if (!tag[p])
cut(t), Link(t, f);
else
{
if (t == p)
{
tag[p] = ;
Link(t, f);
}
else
{
int k = tag[p]; cut(t), Link(t, f); if (find(k) != find(p))
link(p, k), tag[p] = ;
}
}
} int n, m, s[mxn]; signed main(void)
{
scanf("%d%d", &n, &m); for (int i = ; i <= n; ++i)
scanf("%d", s + i); for (int i = ; i <= n; ++i)
{
int t = i + s[i]; if (t < )
Link(i, n + );
else if (t > n)
Link(i, n + );
else
Link(i, t);
} for (int i = ; i <= m; ++i)
{
int opt; scanf("%d", &opt); if (opt == )
{
int t; scanf("%d", &t); int p = find(t); if (tag[p])
puts("-1");
else
{
makeRoot(n + ), access(t);
printf("%d\n", siz[son[t][]]);
}
}
else
{
int a, b; scanf("%d%d", &a, &b); s[a] = b; int t = a + b; if (t < )
change(a, n + );
else if (t > n)
change(a, n + );
else
change(a, t);
}
}
}
@Author: YouSiki
BZOJ 4764: 弹飞大爷的更多相关文章
- BZOJ 4764: 弹飞大爷 LCT
思路并不难,主要是细节需要注意一下. 在 lct 中,删边要写成:f[lson]=0,lson=0 (因为删 x->y 时 y 不一定是左儿子,y 只是 x 的前驱) 然后 f[lson]=ls ...
- 【BZOJ】4764: 弹飞大爷 LCT
[题意]给定n个数字ai,表示大爷落到i处会被弹飞到i+ai处,弹飞到>n或<1处则落地.m次操作,修改一个ai,或询问大爷落到x处经过几次落地(或-1).n,m<=10^5,|ai ...
- 【LCT维护基环内向树森林】BZOJ4764 弹飞大爷
4764: 弹飞大爷 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 101 Solved: 52[Submit][Status][Discuss] ...
- 【BZOJ4764】弹飞大爷 LCT
[BZOJ4764]弹飞大爷 Description 自从WC退役以来,大爷是越来越懒惰了.为了帮助他活动筋骨,也是受到了弹飞绵羊一题的启发,机房的小伙伴们决定齐心合力构造一个下面这样的序列.这个序列 ...
- 【bzoj 4764】弹飞大爷
Description 自从WC退役以来,大爷是越来越懒惰了.为了帮助他活动筋骨,也是受到了弹飞绵羊一题的启发,机房的小伙伴们决定齐心合力构造一个下面这样的序列.这个序列共有N项,每项都代表了一个小伙 ...
- BZOJ4764弹飞大爷——LCT
题目描述 自从WC退役以来,大爷是越来越懒惰了.为了帮助他活动筋骨,也是受到了弹飞绵羊一题的启发,机房的小伙伴们 决定齐心合力构造一个下面这样的序列.这个序列共有N项,每项都代表了一个小伙伴的力量值, ...
- bzoj4764: 弹飞大爷
Description 自从WC退役以来,大爷是越来越懒惰了.为了帮助他活动筋骨,也是受到了弹飞绵羊一题的启发,机房的小伙伴们 决定齐心合力构造一个下面这样的序列.这个序列共有N项,每项都代表了一个小 ...
- [bzoj] 2002 弹飞绵羊 || LCT
原题 简单的LCT练习题. 我们发现对于一个位置x,他只能跳到位置x+k,也就是唯一的父亲去.加入我们将弹飞的绵羊定义为跳到了n+1,那么这就形成了一棵树.而因为要修改k,所以这颗树是动态连边的,那么 ...
- bzoj 2002: 弹飞绵羊 Link-Cut-Tree
题目: Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置, ...
随机推荐
- Linux下端口被占用确认
有时候关闭软件后,后台进程死掉,导致端口被占用.下面以JBoss端口8083被占用为例,列出详细解决过程. 解决方法: 1.查找被占用的端口 netstat -tln netstat -tln | g ...
- Docker中查看Mysql数据库中的各环境参数
通过官方的文档可以看到运行MySQL容器的命令是: docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=mypwd -d mysql:tag 如:d ...
- Codeforces Round #503 Div1+Div2 1019&1020
https://winniechen.cn/?p=188 这个还是直接放链接吧,毕竟内容比较多...
- [Oracle]坏块处理:确认坏块的对象
如果已经知道 FILE#,BLOCK#,则 可以通过如下查询来看: SQL> SELECT SEGMENT_TYPE,OWNER||'.'||SEGMENT_NAME FROM DBA_EXTE ...
- 【干货】YUM安装PHP 7版本后,增加phalcon框架的报错解决
目录 1.yum安装php 7.x版本,此处部署7.3版本 2.安装phalcon框架 2.1.PHP版本依赖关系 2.2.编译phalcon扩展模块 2.3.增加扩展文件 3.部署phalcon遇到 ...
- libgdx学习记录12——圆角矩形CircleRect
libgdx提供了ShapeRenderer这个工具,用它可以画点.画线.画圆.画矩形.画椭圆.画扇形,但是没有提供画圆角矩形的方法. 刚开始自己尝试分成8端,4端画直线,4端画扇形,发现多了半径几部 ...
- Panorama——H5实现全景图片原理
前言 H5是怎么实现全景图片播放呢? 正文 全景图的基本原理即 "等距圆柱投影",这是一种将球体上的各个点投影到圆柱体的侧面上的一种投影方式,投影后再展开就是一张 2:1 的矩形图 ...
- 9、Dockerfile实战-Nginx
上一节我们详解Dockerfile之后,现在来进行实战.我们通过docker build来进行镜像制作. build有如下选项: [root@localhost ~a]# docker build - ...
- git 创建标签和删除标签
创建标签 在Git中打标签非常简单,首先,切换到需要打标签的分支上: $ git branch * dev master $ git checkout master Switched to branc ...
- 基于约束的SQL攻击
前言 值得庆幸的是如今开发者在构建网站时,已经开始注重安全问题了.绝大部分开发者都意识到SQL注入漏洞的存在,在本文我想与读者共同去探讨另一种与SQL数据库相关的漏洞,其危害与SQL注入不相上下,但却 ...