LCT 模板 ——bzoj2002

http://www.lydsy.com/JudgeOnline/problem.php?id=2002

不说了,模板题, 将i的父亲改为i+ki就好。

  1 /*
  2     Name: bzoj2002
  3     Author: rqy
  4     Date: 14/02/17
  5 */
  6 #include<cstdio>
  7 #include<cstring>
  8 #include<algorithm>
  9 const int MAXN = 200010;
 10 struct LCT{
 11     /*--Splay--*/
 12     int fa[MAXN], son[MAXN][2];
 13     int size[MAXN];
 14     bool rev[MAXN];
 15     inline void pd(int x)
 16     {
 17         if(rev[x])
 18         {
 19             rev[son[x][0]] ^= 1;
 20             rev[son[x][1]] ^= 1;
 21             std::swap(son[x][0], son[x][1]);
 22             rev[x] = 0;
 23         }
 24     }
 25     inline void upd(int x)
 26     {
 27         size[x] = 1 + size[son[x][0]] + size[son[x][1]];
 28     }
 29     inline int dir(int x)
 30     {
 31         return (son[fa[x]][0] == x) ? 0 : ((son[fa[x]][1] == x) ? 1 : -1);
 32     }
 33     inline void rotate(int x)
 34     {
 35         int p = fa[x], q = fa[p], d = dir(x), d2 = dir(p);
 36         if(d < 0) return;
 37         if(son[p][d] = son[x][d^1]) fa[son[p][d]] = p;
 38         fa[son[x][d^1] = p] = x;
 39         fa[x] = q;
 40         if(d2 >= 0) son[q][d2] = x;
 41         upd(p);
 42         //??upd(x);
 43     }
 44     int stack[MAXN], st_end;
 45     void splay(int x)
 46     {
 47         int i, j;
 48         for(i = x, st_end = 0; dir(i) >= 0; i = fa[i])
 49             stack[st_end++] = i;
 50         pd(i);
 51         while(st_end--) pd(stack[st_end]);
 52         for(; (i = dir(x)) >= 0; rotate(x))
 53             if((j = dir(fa[x])) >= 0) rotate(i ^ j ? x : fa[x]);
 54         upd(x);
 55     }
 56     /*--LCT--*/
 57     LCT(){
 58         memset(fa, 0, sizeof(fa));
 59         memset(son, 0, sizeof(son));
 60         for(int i = 1; i < MAXN; i++) size[i] = 1;
 61         size[0] = 0;
 62         memset(rev, 0, sizeof(rev));
 63     }
 64     void access(int x)
 65     {
 66         int f;
 67         splay(x);
 68         son[x][1] = 0;
 69     //??upd(x);
 70         while(f = fa[x])
 71         {
 72             splay(f);
 73             son[f][1] = x;
 74             upd(x = f);
 75         }
 76     }
 77     inline void mkroot(int x)
 78     {
 79         access(x);
 80         splay(x);
 81         rev[x] ^= 1;
 82     }
 83     inline void cut(int x, int y)
 84     {
 85         mkroot(x);
 86         access(y);
 87         splay(y);
 88         son[y][0] = fa[x] = 0;
 89         upd(y);
 90     }
 91     inline void link(int x, int y)
 92     {
 93         mkroot(x);
 94         fa[x] = y;
 95         access(x);
 96         splay(x);
 97     }
 98 }; 
 99 LCT T;
100 int nxt[MAXN];
101 int main()
102 {
103     //freopen("in", "r", stdin);
104     int n, m, x, i, j;
105     scanf("%d", &n);
106     for(i = 1; i <= n; i++)
107     {
108         scanf("%d", &x);
109         nxt[i] = T.fa[i] = std::min(i + x, n + 1);
110     }
111     scanf("%d", &m);
112     while(m--)
113     {
114         scanf("%d%d", &x, &i); i++;
115         if(x == 1)
116         {
117             T.mkroot(n + 1);
118             T.access(i);
119             T.splay(i);
120             printf("%d\n", T.size[T.son[i][0]]);
121         }
122         else
123         {
124             scanf("%d", &j);
125             T.cut(i, nxt[i]);
126             T.link(i, nxt[i] = std::min(i + j, n + 1));
127         }
128     }
129     return 0;
130 }
数组实现
  1 /*
  2     Name: bzoj2002
  3     Author: rqy
  4     Date: 15/02/17 09:50, 16/02/17 09:54
  5 */
  6 #include<cstdio>
  7 #include<algorithm>
  8 
  9 struct LCT{
 10   struct Node{
 11     Node *fa, *son[2];
 12     int siz;
 13     bool rev;
 14     Node(Node *fa = NULL, Node *l = NULL, Node *r = NULL) :fa(fa), rev(0), siz(1) {
 15       son[0] = l;
 16       son[1] = r;
 17     }
 18     inline void upd() { siz = son[0]->siz + son[1]->siz + 1; }
 19     inline void pd() {
 20       if (rev) {
 21         son[0]->rev ^= 1;
 22         son[1]->rev ^= 1;
 23         std::swap(son[0], son[1]);
 24         rev = 0;
 25       }
 26     }
 27     inline int tp() { return fa->son[0] == this ? 0 : (fa->son[1] == this ? 1 : -1); }
 28     inline void rotate() {
 29       int d = tp();
 30       if (d < 0) return; 
 31       Node *p = fa;
 32       if ((p->son[d] = son[d^1])->siz) son[d^1]->fa = p;
 33       fa = p->fa;
 34       if (p->tp() >= 0) fa->son[p->tp()] = this;
 35       (son[d^1] = p)->fa = this;
 36       p->upd();
 37       //??upd();
 38     }
 39   };
 40   Node* nil;
 41   Node nodes[200010];
 42   Node* stack[200010];
 43   
 44   void init(int n) {
 45     for (Node *i = nodes; i - nodes < n; ++i)
 46       *i = Node(nil, nil, nil);
 47   }
 48   LCT(int n = 0) {
 49     nil = new Node();
 50     nil->fa = nil->son[0] = nil->son[1] = nil; 
 51     nil->siz = 0;
 52     init(n);
 53   }
 54   void splay(Node *x) {
 55     Node *v = x, **t = stack;
 56     for (; v != nil && v->tp() >= 0; v = v->fa)
 57       *(t++) = v->fa;
 58     while (t != stack)
 59       (*(--t))->pd();
 60     x->pd();
 61     int i, j;
 62     for (v = x->fa; (i = x->tp()) >= 0; x->rotate(), v = x->fa)
 63       if ((j = v->tp()) >= 0)
 64         (i ^ j ? x : v)->rotate();
 65     x->upd();
 66   }
 67   void access(Node *x) {
 68     Node *v;
 69     splay(x);
 70     x->son[1] = nil;
 71     //??x->upd();
 72     while ((v = x->fa) != nil) {
 73       splay(v);
 74       v->son[1] = x;
 75       (x = v)->upd();
 76     }
 77   }
 78   inline void mkroot(Node *x) {
 79     access(x);
 80     splay(x);
 81     x->rev ^= 1;
 82   }
 83   inline void cut(int x, int y) {
 84     //fa[x] == y -> fa[x] = 0
 85     mkroot(nodes + x);
 86     access(nodes + y);
 87     splay(nodes + y);
 88     nodes[y].son[0] = nodes[x].fa = nil;
 89     nodes[y].upd();
 90   }
 91   inline void link(int x, int y) {
 92     //fa[x] == 0 -> fa[x] = y
 93     mkroot(nodes + x);
 94     nodes[x].fa = nodes + y;
 95     access(nodes + x);
 96     splay(nodes + x);
 97   }
 98 };
 99 LCT T;
100 int nxt[200010];
101 int main()
102 {
103   //freopen("in", "r", stdin);
104   int n, m, x, i, j;
105   scanf("%d", &n);
106   T.init(n + 2);
107   for (i = 1; i <= n; i++) {
108     scanf("%d", &x);
109     T.nodes[i].fa = T.nodes + (nxt[i] = std::min(i + x, n + 1));
110   }
111   scanf("%d", &m);
112   while (m--) {
113     scanf("%d%d", &x, &i); i++;
114     if (x == 1) {
115       T.mkroot(T.nodes + n + 1);
116       T.access(T.nodes + i);
117       T.splay(T.nodes + i);
118       printf("%d\n", T.nodes[i].son[0]->siz);
119     } else {
120       scanf("%d", &j);  
121       T.cut(i, nxt[i]);
122       T.link(i, nxt[i] = std::min(i + j, n + 1));
123     }
124   }
125   return 0;
126 }
指针实现
  1 /*
  2     Name: bzoj2002
  3     Author: rqy
  4     Date: 17/02/17 08:03
  5 */
  6 #include<cstdio>
  7 #include<algorithm>
  8 #include<cstring>
  9 const int N = 200010;
 10 int fa[N], son[N][2], siz[N];
 11 bool rev[N];
 12 #define f fa[x]
 13 #define ch son[x]
 14 inline int tp(int x) {
 15   return son[f][0] == x ? 0 :
 16          son[f][1] == x ? 1 : -1;
 17 }
 18 inline void pd(int x) {
 19   if (rev[x]) {
 20     rev[ch[0]] ^= 1;
 21     rev[ch[1]] ^= 1;
 22     std::swap(ch[0], ch[1]);
 23     rev[x] = 0;
 24   }
 25 }
 26 inline void upd(int x) {
 27   siz[x] = siz[ch[0]] + siz[ch[1]] + 1;
 28 }
 29 inline void rotate(int x) {
 30   int p = f, d = tp(x);
 31   f = fa[p];
 32   if (tp(p) >= 0)
 33     son[f][tp(p)] = x;
 34   if (son[p][d] = ch[d ^ 1])
 35     fa[ch[d ^ 1]] = p;
 36   son[fa[p] = x][d ^ 1] = p;
 37   upd(p);
 38   //upd(x);
 39 }
 40 int st[N];
 41 void splay(int x) {
 42   int t = 0, v = x, i, j;
 43   for (; tp(v) >= 0; v = fa[v], ++t)
 44     st[t] = v;
 45   pd(v);
 46   for (; t >= 0; --t)
 47     pd(st[t]);
 48   for (; (i = tp(x)) >= 0; rotate(x))
 49     if((j = tp(f)) >= 0)
 50       rotate(i ^ j ? x : f);
 51   upd(x);
 52 }
 53 void init(int n) {
 54     memset(fa, 0, sizeof(fa));
 55     memset(son, 0, sizeof(son));
 56     for (int i = 1; i <= n; i++) siz[i] = 1;
 57     siz[0] = 0;
 58     memset(rev, 0, sizeof(rev));
 59 }
 60 void access(int x) {
 61   splay(x);
 62   ch[1] = 0;
 63   //upd(x);
 64   for (int v = f; v; v = f) {
 65     splay(v);
 66     son[v][1] = x;
 67     upd(x = v);
 68   }
 69 }
 70 inline void mkroot(int x) {
 71   access(x);
 72   splay(x);
 73   rev[x] ^= 1;
 74 }
 75 inline void cut(int x, int y) {
 76   mkroot(x);
 77   access(y);
 78   splay(y);
 79   son[y][0] = fa[x] = 0;
 80   upd(y);
 81 }
 82 inline void link(int x, int y) {
 83   mkroot(x);
 84   fa[x] = y;
 85   access(x);
 86   splay(x);
 87 }
 88 int nxt[N];
 89 int main()
 90 {
 91     //freopen("in", "r", stdin);
 92     int n, m, x, i, j;
 93     scanf("%d", &n);
 94     init(n + 1);
 95     for(i = 1; i <= n; i++)
 96     {
 97         scanf("%d", &x);
 98         nxt[i] = fa[i] = std::min(i + x, n + 1);
 99     }
100     scanf("%d", &m);
101     while(m--)
102     {
103         scanf("%d%d", &x, &i); i++;
104         if(x == 1)
105         {
106             mkroot(n + 1);
107             access(i);
108             splay(i);
109             printf("%d\n", siz[son[i][0]]);
110         }
111         else
112         {
113             scanf("%d", &j);
114             cut(i, nxt[i]);
115             link(i, nxt[i] = std::min(i + j, n + 1));
116         }
117     }
118     return 0;
119 }
数组实现2

 

posted @ 2017-02-14 10:02  _rqy  阅读(251)  评论(0编辑  收藏