BZOJ 2049 LCT

Orz 黄学长, 当然也要感谢自己(这次打的比较顺利,虽然题目操作很少,也比较简单),加油, 相信自己, 会更强大的, 但还是要虚心, 才会有更大的进步。 不过还是有点不懂,找个时间,问一下czl吧!

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #define rep(i,j,k) for(int i = j; i <= k; i++)
  5 #define lc c[k][0]
  6 #define rc c[k][1]
  7 #define maxn 10233
  8 using namespace std;
  9
 10 int n, m;
 11 int read()
 12 {
 13     int s = 0, t = 1; char c = getchar();
 14     while( !isdigit(c) ){
 15         if( c == ‘-‘ ) t = -1; c = getchar();
 16     }
 17     while( isdigit(c) ){
 18         s = s * 10 + c - ‘0‘; c = getchar();
 19     }
 20     return s * t;
 21 }
 22
 23 int c[maxn][2], pa[maxn];
 24 bool rev[maxn];
 25 int q[maxn];
 26
 27 inline bool root(int x)
 28 {
 29     int k = pa[x];
 30     return lc != x && rc != x;
 31 }
 32
 33 void pushdown(int k)
 34 {
 35     if( rev[k] ){
 36         rev[lc] ^= 1, rev[rc] ^= 1;
 37         swap(lc,rc);
 38         rev[k] ^= 1;
 39     }
 40 }
 41
 42 void rorate(int k)
 43 {
 44     int fa = pa[k], gfa = pa[fa];
 45     int l = c[fa][1] == k, r = l ^ 1;
 46     if( !root(fa) ){
 47         c[gfa][c[gfa][1] == fa] = k;
 48     }
 49     pa[k] = gfa, pa[c[k][r]] = fa, pa[fa] = k;
 50     c[fa][l] = c[k][r]; c[k][r] = fa;
 51 }
 52
 53 void splay(int k)
 54 {
 55     int top = 0;
 56     q[++top] = k;
 57     for( int x = k; !root(x); x = pa[x] ){
 58         q[++top] = pa[x];
 59     }
 60     while( top ) pushdown(q[top--]);
 61     while( !root(k) ){
 62         int fa = pa[k], gfa = pa[fa];
 63         if( !root(fa) ){
 64             if( c[fa][0] == k ^ c[gfa][0] == fa ) rorate(k);
 65             else rorate(fa);
 66         }
 67         rorate(k);
 68     }
 69 }
 70
 71 void access(int x)
 72 {
 73     for(int t = 0; x; t = x, x = pa[x]){
 74         splay(x), c[x][1] = t;
 75     }
 76 }
 77
 78 void makeroot(int x)
 79 {
 80     access(x), splay(x); rev[x] ^= 1;
 81 }
 82
 83 void link(int x,int y)
 84 {
 85     makeroot(x); pa[x] = y; splay(x);
 86 }
 87
 88 void cut(int x,int y)
 89 {
 90     makeroot(x); access(y), splay(y); c[y][0] = pa[x] = 0;
 91 }
 92
 93 int find(int k)
 94 {
 95     access(k); splay(k);
 96     while( lc ) k = lc;
 97     return k;
 98 }
 99
100 bool solve(int x,int y)
101 {
102     if( find(x) == find(y) ) return 1;
103     else return 0;
104 }
105
106 int main()
107 {
108     n = read(), m = read(); char c[10];
109     rep(i,1,m){
110         scanf("%s", c);
111         int x = read(), y = read();
112         if( c[0] == ‘C‘ ){
113             link(x,y);
114         }
115         if( c[0] == ‘Q‘ ){
116             if( solve(x,y) ) puts("Yes");
117             else puts("No");
118         }
119         if( c[0] == ‘D‘ ){
120             cut(x,y);
121         }
122     }
123     return 0;
124 }
时间: 2024-10-09 21:13:05

BZOJ 2049 LCT的相关文章

[BZOJ 2049] [Sdoi2008] Cave 洞穴勘测 【LCT】

题目链接:BZOJ - 2049 题目分析 LCT的基本模型,包括 Link ,Cut 操作和判断两个点是否在同一棵树内. Link(x, y) : Make_Root(x); Splay(x); Father[x] = y; Cut(x, y) : Make_Root(x); Access(y); 断掉 y 和 Son[y][0]; 注意修改 Son[y][0] 的 isRoot 和 Father 判断 x, y 是否在同一棵数内,我们就看两个点所在树的根是否相同,使用 Find_Root()

BZOJ 2049: [Sdoi2008]Cave 洞穴勘测

二次联通门 : BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 其实指针也不是很慢 我的指针代码能吊打70%的数组 及80%的指针.... /* BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 LCT 连边 删边 查询是否在同一树中时, 只需要一直向上跳 看看树根是否相同就好了 */ #include <cstdio> #include <cstdlib> #include <iostream> #define Max 400009 int

bzoj 2631 LCT

/************************************************************** Problem: 2631 User: wangyucheng Language: C++ Result: Accepted Time:18408 ms Memory:9252 kb ****************************************************************/ #include<iostream> #include

BZOJ 2049: [Sdoi2008]Cave 洞穴勘測 LCT

入门级LCT: 仅仅有 Cut Link 2049: [Sdoi2008]Cave 洞穴勘測 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 3073  Solved: 1379 [id=2049" style="color:blue; text-decoration:none">Submit][Status] Description 辉辉热衷于洞穴勘測.某天,他依照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘

【LCT】【SDOI 2008】【bzoj 2049】Cave 洞穴勘测

2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 4805 Solved: 2139 Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通

bzoj 2049 Cave 洞穴勘测(LCT)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 动态树入门题,不需要维护任何信息. 我用的是splay,下标实现的lct. 1 #include <iostream> 2 #include <sstream> 3 #include <ios> 4 #include <iomanip> 5 #include <functional> 6 #include <algorith

BZOJ 2049([Sdoi2008]Cave 洞穴勘测-LCT)[Template:LCT]

2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 4809  Solved: 2141 [Submit][Status][Discuss] Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接

BZOJ 2049 [Sdoi2008]Cave 洞穴勘测 LCT

题意:链接 方法: LCT 解析: 搞了一下午的LCT,这道题就当做第一道模板?题.然后大概写个理解总结什么的. 首先!splay不要写挂!不要写挂! 然后对于这道题.没有什么奇怪的操作. 只有两个操作,将两个节点连起来,将两个节点之间的连边断开. 每一次询问,询问两个节点是否连通. 听起来挺简单的,一下子就想到了并查集有没有! 然而发现并查集并不可以搞. 也许是我太弱,但是我真的不会并查集的分割. 所以还是老老实实来想LCT. LCT 顾名思义,Link Cut 是其比较有代表性的操作? 首先

[bzoj] 2049 洞穴勘探 || LCT

原题 这是一道LCT的板子题. 至于LCT--link cut tree,也叫动态树,用splay实现动态连边的树. 预备知识: 实边:一个非叶节点,向它的儿子中的一个连一条特殊的边,称为实边;该非叶节点向它的其他儿子所引的边均为虚边.注意,对于某些非叶节点,它与它儿子们所连的边可能全部是虚边 LCT的操作: access(x) --将x到根的路径变成实路径(该实路径的端点为根和x) makeroot(x) --将x变为所在树的根节点 findroot(x) --查找x所在树的根节点 link(