• 洛谷 P3203 [HNOI2010]弹飞绵羊


    题解

    题目中编号从 0 开始,方便起见,代码中加上 1 使得从 1 开始。

    首先从 (i) 弹射 (k) 就是指 (i)(i + k) 连边,对于 目标 (gt n) 的全部指向 (n + 1)。询问 (i) 时直接 (access(i, n + 1)),输出这个 Splay 的 (size) 即可。

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 200000 + 5;
    
    int n, m;
    
    namespace LCT
    {
        // PartI. Splay
        int fa[maxn], ch[2][maxn], size[maxn], st[maxn], sz; bool flip[maxn];
        bool inline notroot(int o) {
            return (ch[0][fa[o]] == o) || (ch[1][fa[o]] == o);
        }
        void inline pushdown(int o) {
            if(flip[o]) {
                if(ch[0][o]) flip[ch[0][o]] ^= 1;
                if(ch[1][o]) flip[ch[1][o]] ^= 1;
                swap(ch[0][o], ch[1][o]);
                flip[o] = false;
            }
        }
        void inline pushup(int o) {
            size[o] = size[ch[0][o]] + size[ch[1][o]] + 1;
        }
        void inline rotate(int x) {
            int y = fa[x], z = fa[y], d = ch[1][y] == x;
            if(notroot(y)) ch[y == ch[1][z]][z] = x; fa[x] = z;
            ch[d][y] = ch[d^1][x]; if(ch[d][y]) fa[ch[d][y]] = y; ch[d^1][x] = y; fa[y] = x;
            pushup(y); pushup(x);
        }
        void inline splay(int x) {
    //		printf("In splay
    ");
            int o = x;
            st[sz = 1] = o;
            while(notroot(o)) st[++sz] = o = fa[o];
    //		printf("stack!
    ");
            while(sz) pushdown(st[sz--]);
            while(notroot(x)) {
                int y = fa[x], z = fa[y];
    //			printf("y = %d, z = %d
    ", y, z);
                if(notroot(y)) rotate(((ch[0][z] == y) ^ (ch[0][y] == x)) ? x : y);
                rotate(x);
            }
            pushup(x);
        }
        // debug
        void inline debug() {
            for(int i = 1; i <= n + 1; ++i) {
                printf("%d:"%d"<%d>(%d)[%d, %d]
    ", i, flip[i], size[i], fa[i], ch[0][i], ch[1][i]);
            }
        }
        // PartII. LCT
        void inline access(int x) {
            for(int y = 0; x; y = x, x = fa[x]) {
                splay(x);
                ch[1][x] = y;
                pushup(x);
            }
        }
        void inline makeroot(int x) {
    //		printf("In makeroot.
    ");
            access(x); 
    //		printf("access ok.
    ");
    //		debug();
            splay(x);
            flip[x] ^= 1;
        }
        void inline split(int x, int y) {
            makeroot(x);
    //		printf("makeroot ok.
    ");
    //		debug();
            access(y); splay(y);
        }
        void inline link(int x, int y) {
            makeroot(x);
            fa[x] = y;
        }
        void inline cut(int x, int y) {
            split(x, y);
            fa[x] = ch[0][y] = 0;
            pushup(y);
        }
    }
    
    int opt, i, k;
    int lk[maxn];
    void inline Init()
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i) {
            scanf("%d", &k);
            lk[i] = LCT::fa[i] = (i + k > n) ? n + 1 : i + k;
        }
        scanf("%d", &m);
    }
    
    void inline Solve()
    {
        while(m--) {
    //		LCT::debug();
            scanf("%d %d", &opt, &i);
            ++i;
            if(opt == 1) {
                LCT::split(i, n + 1);
                printf("%d
    ", LCT::size[n + 1] - 1);
            } else {
                scanf("%d", &k);
                LCT::cut(i, lk[i]);
                LCT::link(i, lk[i] = (i + k > n) ? n + 1 : i + k);
            }
    //		printf("ok.
    ");
        }
    }
    
    int main()
    {
        Init();
        Solve();
        return 0;
    }
    
  • 相关阅读:
    Django视图
    Django路由系统
    Django概述,配置文件,web框架本质,Django框架
    Mysql
    R语言之常用函数
    从PCA、PLS-DA、OPLS-DA学习线性代数和矩阵
    算法第一关
    别人处理二代测序的流程
    reportlab包使用指南
    Python 文本(txt) 转换成 EXCEL(xls)
  • 原文地址:https://www.cnblogs.com/cjrsacred/p/10167953.html
Copyright © 2020-2023  润新知