lct 模版题 bzoj 2002 2049

很早就有人给我推荐的模版题,然后我最近才刷的(‘ ‘    ) 昨天的tree 不知道比他们高到哪里去了,我和他谈笑风生啊!

bzoj 2002 弹飞绵羊

重点:这道题的cut和link 由于这道题链的特殊性所以不能用提根的方法搞,可以注意到每一次cut位置一定是前面的一个元素,所以access 上去之后直接把左边的儿子丢掉就行了(我原来的cut 是在不知道两个点的儿子关系时就强行提根(‘ ‘    )) 然后link的时候直接把cut的那一棵splay接过去就行了

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 using namespace std;
  6
  7 const int maxn = 200100;
  8 struct node {
  9     int size, p, data;
 10     node* son[2], *fa;
 11 }tr[maxn];
 12
 13
 14 void test(node* x) {
 15     if(x) {
 16         cout << x-> data <<" " << x-> size <<" "<< x-> p << endl;
 17         for(int i = 0 ; i < 2; ++ i) test(x-> son[i]);
 18     }
 19 }
 20 void update(node* x) {
 21     x-> size = 1;
 22     for(int i = 0; i < 2; ++ i) if(x-> son[i]) x-> size += x-> son[i]-> size;
 23 }
 24
 25 void rotate(node* x, int f) {
 26     node* y = x-> fa;
 27     if(y-> fa) {
 28         if(y-> fa-> son[0] == y) y-> fa-> son[0] = x;
 29         else y-> fa-> son[1] = x;
 30     }
 31     x-> fa = y-> fa, y-> fa = x, x-> p = y-> p, x-> size = y-> size;
 32     y-> son[f] = x-> son[!f];
 33     if(x->son[!f]) x-> son[!f]-> fa = y;
 34     x-> son[!f] = y;
 35     update(y);
 36 }
 37
 38 void splay(node* x, node* f) {
 39     while(x-> fa != f) {
 40         if(x-> fa-> fa == f) {
 41             int a = x-> fa-> son[0] == x ? 0 : 1;
 42             rotate(x, a);
 43         }
 44         else {
 45             node* y = x-> fa, *z = y-> fa;
 46             int a = z-> son[0] == y ? 0 : 1;
 47             int b = y-> son[0] == x ? 0 : 1;
 48             if(a == b) rotate(y, a), rotate(x, b);
 49             else rotate(x, b), rotate(x, a);
 50         }
 51     }
 52 }
 53
 54 void access(int cur) {
 55     node* x = tr + cur; node* y; int pp;
 56     splay(x, NULL);
 57     if(x-> son[1]) x-> son[1]-> p = cur, x-> son[1]-> fa = NULL, x-> son[1] = NULL, update(x);
 58     while((pp = x-> p)) {
 59         y = tr + pp; splay(y, NULL);
 60         if(y-> son[1]) y-> son[1]-> p = pp, y-> son[1]-> fa = NULL, y-> son[1] = NULL, update(y);
 61         y-> son[1] = x, x-> fa = y; update(y);
 62         splay(x, NULL);
 63     }
 64 }
 65
 66 int int_get() {
 67     int x = 0; char c = (char)getchar(); bool f = 0;
 68     while(!isdigit(c) && c != ‘-‘) c = (char)getchar();
 69     if(c == ‘-‘) f = 1, c = (char)getchar();
 70     while(isdigit(c)) {
 71         x = x * 10 + (int)(c - ‘0‘);
 72         c = (char)getchar();
 73     }
 74     if(f) x = -x;
 75     return x;
 76 }
 77
 78 int n, m, px[maxn];
 79
 80 void read() {
 81     n = int_get();
 82     for(int i = 1; i <= n; ++ i) {
 83         int ne = int_get();
 84         px[i] = ne + i > n ? 0 : i + ne;
 85         (tr + i)-> size = 1, (tr + i)-> p = px[i], (tr + i)-> data = i;
 86     }
 87 }
 88
 89 void sov() {
 90     int m = int_get();
 91     while(m --) {
 92         int op = int_get();
 93         if(op == 1) {
 94             int x = int_get() + 1; access(x); printf("%d\n", (tr + x)-> size);
 95         }
 96         else {
 97             int a, b;
 98             a = int_get() + 1, b = int_get();
 99             access(a); node* x = tr + a;
100             if(px[a]) x-> son[0]-> p = 0, x-> son[0]-> fa = NULL, x-> son[0] = NULL; update(x);
101             px[a] = a + b > n ? 0 : a + b;
102             x-> p = px[a];
103         }
104     }
105 }
106
107 int main() {
108     freopen("test.in", "r", stdin);
109     freopen("test.out", "w", stdout);
110     read();
111     sov();
112     return 0;
113 }

bzoj 2049 洞穴勘探

非常裸的操作,不过我查询是在splay上暴力,应该有更好的方法(‘ ‘    )

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 using namespace std;
  6
  7 const int maxn = 21000;
  8
  9 struct node {
 10     int size, p, lr, data;
 11     node *son[2], *fa;
 12 }tr[maxn];
 13
 14 void test(node* x) {
 15     if(x) {
 16         cout << x-> data <<" "<< x-> size <<" "<< x-> p <<" "<< x-> lr << endl;
 17         for(int i = 0; i < 2; ++ i) test(x-> son[i]);
 18     }
 19 }
 20
 21 void update(node* x) {
 22     x-> size = 1;
 23     for(int i = 0; i < 2; ++ i) if(x-> son[i]) x-> size += x-> son[i]-> size;
 24 }
 25
 26 void swap(node* &a, node* &b) {
 27     node* mid = a; a = b, b = mid;
 28 }
 29
 30 void pushdown(node* x) {
 31     if(x && x-> lr) {
 32         swap(x-> son[0], x-> son[1]);
 33         for(int i = 0; i < 2; ++ i) if(x-> son[i]) x-> son[i]-> lr ^= 1;
 34         x-> lr = 0;
 35     }
 36 }
 37
 38 void rotate(node* x, int f) {
 39     node* y = x-> fa;
 40     if(y-> fa) {
 41         if(y-> fa-> son[0] == y) y-> fa-> son[0] = x;
 42         else y-> fa-> son[1] = x;
 43     }
 44     x-> fa = y-> fa, y-> fa = x, x-> size = y-> size, x-> p = y-> p;
 45     y-> son[f] = x-> son[!f];
 46     if(x-> son[!f]) x-> son[!f]-> fa = y;
 47     x-> son[!f] = y;
 48     update(y);
 49 }
 50
 51 void splay(node* x, node* f) {
 52     pushdown(x);
 53     while(x-> fa != f) {
 54         pushdown(x-> fa-> fa), pushdown(x-> fa), pushdown(x);
 55         if(x-> fa-> fa == f) {
 56             int a = x-> fa-> son[0] == x ? 0 : 1;
 57             rotate(x, a);
 58         }
 59         else {
 60             node* y = x-> fa, *z = y-> fa;
 61             int a = z-> son[0] == y ? 0 : 1;
 62             int b = y-> son[0] == x ? 0 : 1;
 63             if(a == b) rotate(y, a), rotate(x, b);
 64             else rotate(x, b), rotate(x, a);
 65         }
 66     }
 67 }
 68
 69 void access(int cur) {
 70     node* x = tr + cur, *y; int pp;
 71     splay(x, NULL); if(x-> son[1]) x-> son[1]-> fa = NULL, x-> son[1]-> p = cur, x-> son[1] = NULL, update(x);
 72     while((pp = x-> p)) {
 73         y = tr + pp; splay(y, NULL);
 74         if(y-> son[1]) y-> son[1]-> fa = NULL, y-> son[1]-> p = pp, y-> son[1] = NULL, update(y);
 75         y-> son[1] = x, x-> fa = y; update(y);
 76         splay(x, NULL);
 77     }
 78 }
 79
 80 void reserve(int cur) {
 81     access(cur);
 82     (tr + cur)-> lr ^= 1;
 83 }
 84
 85 void cut(int a, int b) {
 86     reserve(a), access(b);
 87     (tr + a)-> p = 0, (tr + a)-> fa = NULL, (tr + b)-> son[0] = NULL;
 88     update(tr + a), update(tr + b);
 89 }
 90
 91 void link(int a, int b) {
 92     reserve(a), access(b);
 93     (tr + a)-> p = b;
 94     update(a + tr), update(b + tr);
 95 }
 96
 97 bool query(int a, int b) {
 98     reserve(a); access(b);
 99     node* x = tr + a;
100     while(x-> fa) x = x-> fa;
101     return x == (tr + b);
102 }
103
104 int int_get() {
105     int x = 0; char c = (char)getchar(); bool f = 0;
106     while(!isdigit(c) && c != ‘-‘ ) c = (char)getchar();
107     if(c == ‘-‘) c = (char)getchar(), f = 1;
108     while(isdigit(c)) {
109         x = x * 10 + (int)(c - ‘0‘);
110         c = (char)getchar();
111     }
112     if(f) x = -x;
113     return x;
114 }
115
116 int n, m;
117
118 void sov() {
119     n = int_get(), m = int_get();
120     for(int i = 1; i <= n; ++ i) (tr + i)-> size = 1, (tr + i)-> p = (tr + i)-> lr = 0, (tr + i)-> data = i;
121     while(m --) {
122         char s[10]; scanf("%s", s + 1);
123         int a, b; a = int_get(), b = int_get();
124         if(s[1] == ‘C‘) link(a, b);
125         if(s[1] == ‘D‘) cut(a, b);
126         if(s[1] == ‘Q‘) {
127             if(query(a, b)) printf("Yes\n");
128             else printf("No\n");
129         }
130     }
131 }
132
133 int main() {
134     //freopen("test.in", "r", stdin);
135     sov();
136    // test(tr + 123);
137 }

时间: 2024-10-14 01:36:34

lct 模版题 bzoj 2002 2049的相关文章

bzoj 2002

2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 3848  Solved: 2051[Submit][Status] Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki

一些LCT裸题

又来回炉lct了= = [bzoj3514]: Codechef MARCH14 GERALD07加强版 模版题.常见姿势,把边也当成点. 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 const int maxn=200233<<1; 6 const int inf=1000023333; 7 struct zs{ 8 int u,v

【BZOJ 2002】 [Hnoi2010]Bounce 弹飞绵羊

2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 4204  Solved: 2255 [Submit][Status] Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+

HDU 2896 病毒侵袭(AC自动机模版题)

AC自动模版题,中文题目就不叙述题意了啊. AC自动主要是构造出字典树之后找到fail指针的跳转,类似于KMP里面的next数组的跳转啊,注意这里是多模式跳转.意思就是这个串跳到下一个串的什么位置啊. 先帖一下,做多了再一起总结吧. 病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11347    Accepted Submi

UVa 12534 Binary Matrix 2 zkw费用流模版题

题目链接:点击打开链接 思路: 我们首先假设这个图都是全0的 用n个点代表行,m个点代表列 用源点向行连一个值x 表示每行1的个数,向列连一个y表示每列y个1 则若行i和列j之间流过一个流量就表示 (i,j) 点填了1 那么若原来图中(i,j)点为0 则花费就是1 若原图中(i,j)点是1,则花费是-1 如此枚举x跑个费用流就好了 ==居然把我多年的白书费用流坑掉了... zkw走起啊 #include <stdio.h> #include <string.h> #include

HDU3966 Aragorn&#39;s Story(树链剖分 点权 模版题)

#include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <queue> #include <map> #include <set> #include <vector> #include <cstdio> using namespace std; const int N=50010; s

poj 2299 Ultra-QuickSort 逆序对模版题

用树状数组求逆序对 唯一的坑点就是sum要用long long存 直接贴代码了 以后忘了还能直接看 2333…… PS:和hdu3743代码是一样的,因为两个都是逆序对模版题…… 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 int s[500005]; 6 int N; 7 struct num{ 8 int xuhao,num; 9 }n

【POJ3159】Candies 裸的pqspfa模版题

不多说了,就是裸的模版题. 贴代码: <span style="font-family:KaiTi_GB2312;font-size:18px;">#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 30500 #define M 200000 #define

2014鞍山网络预选赛1006(LCT模板题)hdu5002

Tree Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 41    Accepted Submission(s): 10 Problem Description You are given a tree with N nodes which are numbered by integers 1..N. Each node is as