zoukankan      html  css  js  c++  java
  • [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;
        
    }
  • 相关阅读:
    hdu 1199 Color the Ball 离散线段树
    poj 2623 Sequence Median 堆的灵活运用
    hdu 2251 Dungeon Master bfs
    HDU 1166 敌兵布阵 线段树
    UVALive 4426 Blast the Enemy! 计算几何求重心
    UVALive 4425 Another Brick in the Wall 暴力
    UVALive 4423 String LD 暴力
    UVALive 4872 Underground Cables 最小生成树
    UVALive 4870 Roller Coaster 01背包
    UVALive 4869 Profits DP
  • 原文地址:https://www.cnblogs.com/evenbao/p/10159285.html
Copyright © 2011-2022 走看看