zoukankan      html  css  js  c++  java
  • [bzoj2002][Hnoi2010]Bounce 弹飞绵羊(LCT)

    题目链接

    第一次做LCT的题目还有点小激动QAQ

    如果将题目所给的关系简化,将弹飞看做是树的根节点,则整个序列就可以看做是一棵树。然后修改操作就是修改一个节点的父节点,查询操作就是查询一个节点的深度。

    如果是修改操作,就是先断边再连边,如果是查询操作,就将x与根节点连在一颗splay中,然后查询这颗splay的节点数,这个就是我们维护的siz大小+1。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 3e5 + 10;
     5 int fa[maxn], ch[maxn][2], siz[maxn], val[maxn], lazy[maxn], st[maxn];//父亲节点,左右儿子节点,当前子数节点个数,当前值,lazy标记,辅助数组。
     6 inline int read() {
     7     int x = 0, f = 1; char ch = getchar();
     8     while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
     9     while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - 48; ch = getchar(); }
    10     return x * f;
    11 }
    12 inline bool isroot(int x) {//判断x是否为所在splay的根
    13     return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
    14 }
    15 inline void pushup(int x) {
    16     siz[x] = siz[ch[x][1]] + siz[ch[x][0]] + 1;
    17 }
    18 inline void pushdown(int x) {
    19     if (lazy[x]) {
    20         swap(ch[x][0], ch[x][1]);
    21         if (ch[x][0])lazy[ch[x][0]] ^= 1;
    22         if (ch[x][1])lazy[ch[x][1]] ^= 1;
    23         lazy[x] = 0;
    24     }
    25 }
    26 inline void rotate(int x) {
    27     int y = fa[x], z = fa[y];
    28     int k = ch[y][1] == x;
    29     if (!isroot(y))
    30         ch[z][ch[z][1] == y] = x;
    31     fa[x] = z; ch[y][k] = ch[x][k ^ 1]; fa[ch[x][k ^ 1]] = y;
    32     ch[x][k ^ 1] = y; fa[y] = x;
    33     pushup(y);
    34     pushup(x);
    35 }
    36 inline void splay(int x) {
    37     int f = x, len = 0;
    38     st[++len] = f;
    39     while (!isroot(f))st[++len] = f = fa[f];
    40     while (len)pushdown(st[len--]);
    41     while (!isroot(x)) {
    42         int y = fa[x];
    43         int z = fa[y];
    44         if (!isroot(y))
    45             rotate((ch[y][0] == x) ^ (ch[z][0] == y) ? x : y);
    46         rotate(x);
    47     }
    48     pushup(x);
    49 }
    50 inline void access(int x) {//打通根节点到x的实链
    51     for (int y = 0; x; x = fa[y = x])
    52         splay(x), ch[x][1] = y, pushup(x);
    53 }
    54 inline void makeroot(int x) {//将x变为原树的根
    55     access(x); splay(x); lazy[x] ^= 1;
    56 }
    57 int Findroot(int x) {//找根节点
    58     access(x), splay(x);
    59     while (ch[x][0])
    60         pushdown(x), x = ch[x][0];
    61     splay(x);
    62     return x;
    63 }
    64 inline void split(int x, int y) { makeroot(x); access(y); splay(y); }
    65 inline void Link(int x, int y) { makeroot(x); fa[x] = y; }
    66 inline void cut(int x, int y) { makeroot(x); access(y); splay(y); fa[x] = ch[y][0] = 0; pushup(y); }//合法断边
    67 int main() {
    68     int n, m;
    69     n = read();
    70     for (int i = 1; i <= n; i++) {
    71         val[i] = read();
    72         if (i + val[i] <= n)
    73             Link(i, i + val[i]);
    74         else
    75             Link(i, n + 1);
    76     }
    77     m = read();
    78     while (m--) {
    79         int opt, x, y;
    80         opt = read(), x = read() + 1;
    81         if (opt == 2) {
    82             y = read();
    83             cut(x, x + val[x] <= n ? x + val[x] : n + 1);
    84             Link(x, x + y <= n ? x + y : n + 1);
    85             val[x] = y;
    86         }
    87         else {
    88             split(x, n + 1);
    89             printf("%d
    ", siz[n + 1] - 1);
    90         }
    91     }92 }
  • 相关阅读:
    第一章 Java入门
    2020-2021-2 网络对抗技术 20181321 Exp 8 Web基础
    2020-2021-2 网络对抗技术 20181321 Exp7 网络欺诈防范
    2020-2021-2 网络对抗技术 20181321 Exp6 MSF基础应用
    Weblogic漏洞复现:CVE-2020-14882未授权代码执行
    利用cse-2020-16127,cve-2020-16125进行漏洞再现
    实验一-密码引擎-加密API实现与测试
    实验一-密码引擎-加密API研究
    API标准
    020-2021-2 网络对抗技术 20181321 Exp5 信息搜集与漏洞扫描
  • 原文地址:https://www.cnblogs.com/sainsist/p/11414631.html
Copyright © 2011-2022 走看看