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个装置, ...
随机推荐
- Xcode添加全局引用文件pch
Xcode6之前有PrefixHeader.pch文件在写项目的时候,大部分宏定义.头文件都导入在这个pch文件,虽然方便,但会增加Build的时间,所以Xcode6以及之后的版本去除了PrefixH ...
- odoo tree视图 当页不弹窗显示方法
<xpath expr="//tree" position="attributes"> <attribute name='editable'& ...
- 从源代码解释Android事件分发机制
在ViewRootImpl的setView方法中.用户的触摸按键消息是体如今窗体上的.而windowManagerService则是管理这些窗体,它一旦接收到用户对窗体的一些触摸按键消息,会进行对应的 ...
- Centos7 安装ELK日志分析
1.安装前准备 借鉴:https://www.cnblogs.com/straycats/p/8053937.html 操作系统:Centos7 虚拟机 8G内存 jdk8+ 软件包下载:采用rp ...
- Ueditor使用笔记
富文本编辑器在javaweb项目中还是比较常见的,如:ckeditor.kindeditor.ueditor等.今天主要叙述的对象为ueditor,它属于百度的.闲话不多说,下面开始介 ...
- 基于AngularJs的单页面程序
基于AngularJs的单页面程序 在Abpzero的后台管理系统是一个AngularJs的单页面程序.当你登陆后,系统会跳转到"ApplicationController",然后 ...
- tomcat-内存溢出java.lang.OutOfMemoryErrory:PermGen space解决方法
如果是PermGen space方法区内存溢出,可尝试加大MaxPermSize,如果是heap space 堆内存移除,可尝试修改Xmx 正常解决方法: 在注释下的第一行添加: JAVA_OPTS= ...
- arduino按钮使用的两个小实验
一:按钮控制一个灯 ...
- nginx反向代理tomcat应用,struts2网站程序redirect时导致请求地址错误的解决方法
一个使用struts2的网站在登录页面需要进行redirect跳转,大致如下: <package name="admin" extends="httl-defaul ...
- 原生和jquery 的 ajax
form数据的序列化: $('#submit').click(function(){ $('#form').serialize(); //会根据input里面的name,把数据序列化成字符串:eg:n ...