lct 模版题 bzoj 2002 2049
很早就有人给我推荐的模版题,然后我最近才刷的(' ' ) 昨天的tree 不知道比他们高到哪里去了,我和他谈笑风生啊!
bzoj 2002 弹飞绵羊
重点:这道题的cut和link 由于这道题链的特殊性所以不能用提根的方法搞,可以注意到每一次cut位置一定是前面的一个元素,所以access 上去之后直接把左边的儿子丢掉就行了(我原来的cut 是在不知道两个点的儿子关系时就强行提根(' ' )) 然后link的时候直接把cut的那一棵splay接过去就行了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = ;
struct node {
int size, p, data;
node* son[], *fa;
}tr[maxn]; void test(node* x) {
if(x) {
cout << x-> data <<" " << x-> size <<" "<< x-> p << endl;
for(int i = ; i < ; ++ i) test(x-> son[i]);
}
}
void update(node* x) {
x-> size = ;
for(int i = ; i < ; ++ i) if(x-> son[i]) x-> size += x-> son[i]-> size;
} void rotate(node* x, int f) {
node* y = x-> fa;
if(y-> fa) {
if(y-> fa-> son[] == y) y-> fa-> son[] = x;
else y-> fa-> son[] = x;
}
x-> fa = y-> fa, y-> fa = x, x-> p = y-> p, x-> size = y-> size;
y-> son[f] = x-> son[!f];
if(x->son[!f]) x-> son[!f]-> fa = y;
x-> son[!f] = y;
update(y);
} void splay(node* x, node* f) {
while(x-> fa != f) {
if(x-> fa-> fa == f) {
int a = x-> fa-> son[] == x ? : ;
rotate(x, a);
}
else {
node* y = x-> fa, *z = y-> fa;
int a = z-> son[] == y ? : ;
int b = y-> son[] == x ? : ;
if(a == b) rotate(y, a), rotate(x, b);
else rotate(x, b), rotate(x, a);
}
}
} void access(int cur) {
node* x = tr + cur; node* y; int pp;
splay(x, NULL);
if(x-> son[]) x-> son[]-> p = cur, x-> son[]-> fa = NULL, x-> son[] = NULL, update(x);
while((pp = x-> p)) {
y = tr + pp; splay(y, NULL);
if(y-> son[]) y-> son[]-> p = pp, y-> son[]-> fa = NULL, y-> son[] = NULL, update(y);
y-> son[] = x, x-> fa = y; update(y);
splay(x, NULL);
}
} int int_get() {
int x = ; char c = (char)getchar(); bool f = ;
while(!isdigit(c) && c != '-') c = (char)getchar();
if(c == '-') f = , c = (char)getchar();
while(isdigit(c)) {
x = x * + (int)(c - '');
c = (char)getchar();
}
if(f) x = -x;
return x;
} int n, m, px[maxn]; void read() {
n = int_get();
for(int i = ; i <= n; ++ i) {
int ne = int_get();
px[i] = ne + i > n ? : i + ne;
(tr + i)-> size = , (tr + i)-> p = px[i], (tr + i)-> data = i;
}
} void sov() {
int m = int_get();
while(m --) {
int op = int_get();
if(op == ) {
int x = int_get() + ; access(x); printf("%d\n", (tr + x)-> size);
}
else {
int a, b;
a = int_get() + , b = int_get();
access(a); node* x = tr + a;
if(px[a]) x-> son[]-> p = , x-> son[]-> fa = NULL, x-> son[] = NULL; update(x);
px[a] = a + b > n ? : a + b;
x-> p = px[a];
}
}
} int main() {
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
read();
sov();
return ;
}
bzoj 2049 洞穴勘探
非常裸的操作,不过我查询是在splay上暴力,应该有更好的方法(' ' )
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = ; struct node {
int size, p, lr, data;
node *son[], *fa;
}tr[maxn]; void test(node* x) {
if(x) {
cout << x-> data <<" "<< x-> size <<" "<< x-> p <<" "<< x-> lr << endl;
for(int i = ; i < ; ++ i) test(x-> son[i]);
}
} void update(node* x) {
x-> size = ;
for(int i = ; i < ; ++ i) if(x-> son[i]) x-> size += x-> son[i]-> size;
} void swap(node* &a, node* &b) {
node* mid = a; a = b, b = mid;
} void pushdown(node* x) {
if(x && x-> lr) {
swap(x-> son[], x-> son[]);
for(int i = ; i < ; ++ i) if(x-> son[i]) x-> son[i]-> lr ^= ;
x-> lr = ;
}
} void rotate(node* x, int f) {
node* y = x-> fa;
if(y-> fa) {
if(y-> fa-> son[] == y) y-> fa-> son[] = x;
else y-> fa-> son[] = x;
}
x-> fa = y-> fa, y-> fa = x, x-> size = y-> size, x-> p = y-> p;
y-> son[f] = x-> son[!f];
if(x-> son[!f]) x-> son[!f]-> fa = y;
x-> son[!f] = y;
update(y);
} void splay(node* x, node* f) {
pushdown(x);
while(x-> fa != f) {
pushdown(x-> fa-> fa), pushdown(x-> fa), pushdown(x);
if(x-> fa-> fa == f) {
int a = x-> fa-> son[] == x ? : ;
rotate(x, a);
}
else {
node* y = x-> fa, *z = y-> fa;
int a = z-> son[] == y ? : ;
int b = y-> son[] == x ? : ;
if(a == b) rotate(y, a), rotate(x, b);
else rotate(x, b), rotate(x, a);
}
}
} void access(int cur) {
node* x = tr + cur, *y; int pp;
splay(x, NULL); if(x-> son[]) x-> son[]-> fa = NULL, x-> son[]-> p = cur, x-> son[] = NULL, update(x);
while((pp = x-> p)) {
y = tr + pp; splay(y, NULL);
if(y-> son[]) y-> son[]-> fa = NULL, y-> son[]-> p = pp, y-> son[] = NULL, update(y);
y-> son[] = x, x-> fa = y; update(y);
splay(x, NULL);
}
} void reserve(int cur) {
access(cur);
(tr + cur)-> lr ^= ;
} void cut(int a, int b) {
reserve(a), access(b);
(tr + a)-> p = , (tr + a)-> fa = NULL, (tr + b)-> son[] = NULL;
update(tr + a), update(tr + b);
} void link(int a, int b) {
reserve(a), access(b);
(tr + a)-> p = b;
update(a + tr), update(b + tr);
} bool query(int a, int b) {
reserve(a); access(b);
node* x = tr + a;
while(x-> fa) x = x-> fa;
return x == (tr + b);
} int int_get() {
int x = ; char c = (char)getchar(); bool f = ;
while(!isdigit(c) && c != '-' ) c = (char)getchar();
if(c == '-') c = (char)getchar(), f = ;
while(isdigit(c)) {
x = x * + (int)(c - '');
c = (char)getchar();
}
if(f) x = -x;
return x;
} int n, m; void sov() {
n = int_get(), m = int_get();
for(int i = ; i <= n; ++ i) (tr + i)-> size = , (tr + i)-> p = (tr + i)-> lr = , (tr + i)-> data = i;
while(m --) {
char s[]; scanf("%s", s + );
int a, b; a = int_get(), b = int_get();
if(s[] == 'C') link(a, b);
if(s[] == 'D') cut(a, b);
if(s[] == 'Q') {
if(query(a, b)) printf("Yes\n");
else printf("No\n");
}
}
} int main() {
//freopen("test.in", "r", stdin);
sov();
// test(tr + 123);
}
lct 模版题 bzoj 2002 2049的更多相关文章
- 以 BZOJ 2002 为例学习有根树LCT(Link-Cut Tree)
以BZOJ 2002 弹飞绵羊为例学习有根树LCT(Link-Cut Tree) 注:本文非常简单,只涉及有根树LCT,对于无根树,LCT还有几个本文没有提到的操作,以后慢慢更新 =v= 知识储备 [ ...
- BZOJ 2002 && BZOJ 2409 LCT && BZOJ 3282 初步练习
#include <cstdio> ; inline void Get_Int(int & x) { ; ') ch=getchar(); +ch-'; ch=getchar(); ...
- 【BZOJ】2049: [Sdoi2008]Cave 洞穴勘测 LCT
[题意]给定n个点和m个操作,每次操作:1.连接2个点.2.断开2个点.3.查询2个点是否连通.m<=2*10^5. [算法]Link-Cut Tree [题解]LCT模板题,Link,Cut, ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 9071 Solved: 4652[Submi ...
- bzoj 2002 Bounce 弹飞绵羊
bzoj 2002 Bounce 弹飞绵羊 设一个虚拟节点表示被弹飞,则每个点的后继点是唯一确定的,每个点向它的后继点连边,就形成了一颗树. 询问就是问某个节点到虚拟节点的路径长度,修改就删除原来向后 ...
- [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)
[BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree) 题面 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一 ...
- 【poj 1962】Corporative Network(图论--带权并查集 模版题)
P.S.我不想看英文原题的,但是看网上题解的题意看得我 炒鸡辛苦&一脸懵 +_+,打这模版题的代码也纠结至极了......不得已只能自己翻译了QwQ . 题意:有一个公司有N个企业,分成几个网 ...
- HDU 2222 Keywords Search(AC自动机模版题)
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- PAT (Top Level) Practise 1008 Airline Routes(Tarjan模版题)
1008. Airline Routes (35) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue Given a ...
随机推荐
- 【leetcode】987. Vertical Order Traversal of a Binary Tree
题目如下: Given a binary tree, return the vertical order traversal of its nodes values. For each node at ...
- 科学把妹法 ( ̄▽ ̄)"
曾经有一位生物学人士,公布了工科把妹第一弹,暨“巴甫洛夫把妹法”: 每天给你那位心仪的女同事/女同学的抽屉里都放上精心准备的早餐,并且保持缄默不语,无论她如何询问,都不要说话. 如此坚持一至两个月, ...
- mysql查询诊断分析工具
Query Profiler是MYSQL自带的一种query诊断分析工具,通过它可以分析出一条SQL语句的性能瓶颈在什么地方.通常我们是使用的explain,以及slow query log都无法做到 ...
- 在Delphi中使用系统对应文件类型的图标
在应用程序的编写中,组合框(ComboBox).列表框(ListBox).等常见的部件,通常不仅要用于显示文字,而且还要显示其与文字相关的图标.在一般的Windows应用程序中,这些图标的显示都要随列 ...
- nodejs在Windows 7上的搭建
一.安装nodejs 去官网下载https://nodejs.org/download/,我选择下载node-v9.3.0-x64.msi ,最新版本, 安装路径放在了D盘,因为C盘的空间不够了,直接 ...
- apache的tomcat负载均衡和集群配置 "
略看了一下,感觉太复杂,要配置的东西太多,因此在这里写出一种更简洁的方法. 要集群tomcat主要是解决SESSION共享的问题,因此我利用memcached来保存session,多台TOMCAT服务 ...
- java并发编程笔记(二)——并发工具
java并发编程笔记(二)--并发工具 工具: Postman:http请求模拟工具 Apache Bench(AB):Apache附带的工具,测试网站性能 JMeter:Apache组织开发的压力测 ...
- 6、基于highcharts实现的线性拟合,计算部分在java中实现,画的是正态概率图
1.坐标点类 package cn.test.domain; public class Point { double x; double y; public Point(){ } public Poi ...
- Linux常用信号快捷键的使用
ctrl-c 发送 SIGINT 信号给前台进程组中的所有进程.常用于终止正在运行的程序.ctrl-z 发送 SIGTSTP 信号给前台进程组中的所有进程,常用于挂起一个进程.ctrl-d 不是发送信 ...
- ZABBIX 忘记登录密码
ZABBIX 忘记登录密码 摘要 有些童鞋会忘记zabbix的登陆密码,今天给大家写一篇找回登陆密码~ ZABBIX 忘记登录密码 zabbix 刚刚在群里吹牛逼,由于账号比较多,脑子容易 ...