[HNOI 2010] 弹飞绵羊

[题目链接]

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

[算法]

        LCT动态维护森林连通性

        时间复杂度 : O(NlogN ^ 2)

[代码]

        

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

int n;
int k[MAXN];

struct Link_Cut_Tree
{
        struct Node
        {
                int father , son[2] , size;
                bool tag;
        } a[MAXN];
        inline void init()
        {    
                for (int i = 1; i <= n; i++)
                {
                        a[i].father = 0;
                        a[i].son[0] = a[i].son[1] = 0;
                        a[i].size = 1;
                        a[i].tag = false;
                }
        }
        inline void pushdown(int x)
        {
                if (a[x].tag)
                {
                        swap(a[x].son[0] , a[x].son[1]);
                        a[a[x].son[0]].tag ^= 1;
                        a[a[x].son[1]].tag ^= 1;
                        a[x].tag = false;
                }
        }
        inline void update(int x)
        {
                a[x].size = 1;
                if (a[x].son[0]) a[x].size += a[a[x].son[0]].size;
                if (a[x].son[1]) a[x].size += a[a[x].son[1]].size;
        }
        inline bool get(int x)
        {
                pushdown(a[x].father);
                return a[a[x].father].son[1] == x;
        }
        inline bool nroot(int x)
        {
                return a[a[x].father].son[0] == x | a[a[x].father].son[1] == x;
        }
        inline void rotate(int x)
    {
        int f = a[x].father , g = a[f].father;                        
        int tmpx = get(x) , tmpf = get(f);
        int w = a[x].son[tmpx ^ 1];
        if (nroot(f)) a[g].son[tmpf] = x;
        a[x].son[tmpx ^ 1] = f;
        a[f].son[tmpx] = w;
        if (w) a[w].father = f;
        a[f].father = x;
        a[x].father = g;
        update(f);
    }
        inline void access(int x)
        {
                for (int y = 0; x; x = a[y = x].father)
                {
                        splay(x);
                        a[x].son[1] = y;
                        update(x);
                }
        }
        inline void splay(int x)
    {
        int y = x , z = 0;
        static int st[MAXN];
        st[++z] = y;
        while (nroot(y)) st[++z] = y = a[y].father;
        while (z) pushdown(st[z--]);
        while (nroot(x))
        {
            int y = a[x].father , z = a[y].father;
            if (nroot(y))
                rotate((a[y].son[0] == x) ^ (a[z].son[0] == y) ? x : y);
            rotate(x);
        }
        update(x);
    }
        inline void make_root(int x)
        {
                access(x);
                splay(x);
                a[x].tag ^= 1;
                pushdown(x);
        }
        inline int find_root(int x)
        {
                access(x);
                splay(x);
                while (a[x].son[0])
                {
                        pushdown(x);
                        x = a[x].son[0];
                }
                return x;
        }
        inline void link(int x , int y)
        {
                make_root(x);
                if (find_root(y) != x) a[x].father = y;        
        }
        inline void cut(int x , int y)
        {
                make_root(x);
                if (find_root(y) == x && a[x].father == y && !a[x].son[1])
                {
                        a[x].father = a[y].son[0] = 0;
                        update(y);
                 }
        }
        inline int query(int u)
        {
                make_root(u);
                access(n + 1);
                splay(n + 1);
                return a[n + 1].size - 1;
        }
        inline void modify(int u , int val)
        {
                if (u + k[u] <= n) cut(u , u + k[u]);
                else cut(u , n + 1);
                if (u + val <= n) link(u , u + val);
                else link(u , n + 1);
                k[u] = val;
        }
} LCT;

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}

int main()
{
        
        read(n);
        LCT.init();
        for (int i = 1; i <= n; i++) 
        {
                read(k[i]);
                if (i + k[i] <= n) LCT.link(i , i + k[i]);
                else LCT.link(i , n + 1);
        }
        int m;
        read(m);
        while (m--)
        {
                int type;
                read(type);
                if (type == 1)
                {
                        int x;
                        read(x);
                        ++x;
                        printf("%d
" , LCT.query(x));        
                }    else
                {
                        int x , val;
                        read(x); read(val);
                        ++x;
                        LCT.modify(x , val);
                }
        }
        
        return 0;
    
}
原文地址:https://www.cnblogs.com/evenbao/p/10159285.html