• 【题解】 Luogu P4312 / SP4155 [COCI 2009] OTOCI / 极地旅行社


    原题地址:P4312 [COCI 2009] OTOCI / 极地旅行社/SP4155 OTOCI - OTOCI

    lct入门难度的题,十分弱智(小蒟蒻说lct是什么,能吃吗?)

    bridge操作判联通,用find,不同的话link一下

    penguins修改点权,把这个点旋转到树根暴力修改并pushup

    excursion先判联通,如果联通输出点权之和

    操作就是这样,简单有点像P2147 [SDOI2008]洞穴勘测

    代码:

    #pragma GCC optimize("O3")
    #include <bits/stdc++.h>
    #define N 300005
    using namespace std;
    inline int read()
    {
        int f=1,x=0;char ch;
        do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
        do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
        return f*x;
    }
    inline void Swap(register int &a,register int &b)
    {
        a^=b^=a^=b;
    }
    int n,m,v[N];
    struct Link_cut_tree{
        int top,c[N][2],fa[N],q[N],rev[N],sum[N];
        inline void pushup(register int x)
        {
        	sum[x]=sum[c[x][0]]+sum[c[x][1]]+v[x];
        }
        inline void pushdown(int x)
        {
            int l=c[x][0],r=c[x][1];
            if(rev[x])
            {
                rev[l]^=1;
                rev[r]^=1;
                rev[x]^=1;
                Swap(c[x][0],c[x][1]);
            }
        }
        inline bool isroot(int x)
        {
            return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
        }
        inline void rotate(int x)
        {
            int y=fa[x],z=fa[y],l,r;
            if(c[y][0]==x)
                l=0;
            else
                l=1;
            r=l^1;
            if(!isroot(y))
            {
                if(c[z][0]==y)
                    c[z][0]=x;
                else
                    c[z][1]=x;
            }
            fa[x]=z;
            fa[y]=x;
            fa[c[x][r]]=y;
            c[y][l]=c[x][r];
            c[x][r]=y;
            pushup(y);
            pushup(x);
        }
        inline void splay(int x)
        {
            top=1;
            q[top]=x;
            for(register int i=x;!isroot(i);i=fa[i])
                q[++top]=fa[i];
            for(register int i=top;i;--i)
                pushdown(q[i]);
            while(!isroot(x))
            {
                int y=fa[x],z=fa[y];
                if(!isroot(y))
                {
                    if((c[y][0]==x)^(c[z][0]==y))
                        rotate(x);
                    else
                        rotate(y);
            	}
                rotate(x);
            }
            pushup(x);
        }
        inline void access(int x)
        {
            for(register int t=0;x;t=x,x=fa[x])
            {
                splay(x);
                c[x][1]=t;
                pushup(x);
            }
        }
        inline void makeroot(int x)
        {
            access(x);
            splay(x);
            rev[x]^=1;
        }
        inline int find(int x)
        {
            access(x);
            splay(x);
            while(c[x][0])
                x=c[x][0];
            return x;
        }
        inline void split(int x,int y)
        {
            makeroot(x);
            access(y);
            splay(y);
        }
        inline void cut(int x,int y)
        {
            split(x,y);
            if(c[y][0]==x)
            {
                c[y][0]=0;
                fa[x]=0;
            }
        }
        inline void link(int x,int y)
        {
            makeroot(x);
            fa[x]=y;
        }
    }T;
    int main()
    {
        n=read();
        for(register int i=1;i<=n;++i)
        {
        	v[i]=read();
        	T.sum[i]=v[i];
        }
        m=read();
        while(m--)
        {
            char c[10];
            scanf("%s",c);
            int x=read(),y=read();
            if(c[0]=='b')
            {
                if(T.find(x)==T.find(y))
                    puts("no");
                else
                {
                    puts("yes");
                    T.link(x,y);
                }
            }
            else if(c[0]=='p')
            {
                T.access(x);
                T.splay(x);
                v[x]=y;
                T.pushup(x);
            }
            else
            {
                if(T.find(x)!=T.find(y))
                    puts("impossible");
                else
                {
                    T.split(x,y);
                    printf("%d
    ",T.sum[y]);
                }
            }
        }
        return 0;
    }
    

    lct真简单

  • 相关阅读:
    关于MATLAB处理大数据坐标文件2017628
    回溯算法
    [leetcode] 046. Permutations 解题报告
    [leetcode] 226. Invert Binary Tree 解题报告
    [leetcode] 121. Best Time to Buy and Sell Stock 解题报告
    [leetcode] 112. Path Sum 解题报告
    [leetcode] 190. Reverse Bits 解题报告
    [leetcode] 189. Rotate Array 解题报告
    [leetcode] 100. Same Tree 解题报告
    [leetcode] 88. Merge Sorted Array 解题报告
  • 原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/9652332.html
Copyright © 2020-2023  润新知