zoukankan      html  css  js  c++  java
  • [LCT]luogu P3203 弹飞绵羊

    https://www.luogu.org/problem/P3203

    分析

    还有个模板不想写题解了,反正这题也差不多是个模板

    可以将一个点往后跳跃到的点连起来,跳出去的连到根节点+1,这就是棵树

    要求支持删边连边和求根节点到这里的深度?LCT完全可以胜任

    就是个板子,深度不用特别思考,Split直接提出来的是链,求Splay大小即可

    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int N=2e5+10; 
    struct Node {
        int f,c[2],s,rev;
    }t[N];
    int stk[N],top,v[N];
    int n,m;
    
    bool Witch(int x) {return x==t[t[x].f].c[1];}
    
    bool Check_Root(int x) {return t[t[x].f].c[0]==x||t[t[x].f].c[1]==x;}
    
    void Reverse(int x) {swap(t[x].c[0],t[x].c[1]),t[x].rev^=1;}
    
    void Pushdown(int x) {if (t[x].rev) Reverse(t[x].c[0]),Reverse(t[x].c[1]),t[x].rev=0;}
    
    void Update(int x) {t[x].s=t[t[x].c[0]].s+t[t[x].c[1]].s+1;}
    
    void Rotate(int x) {
        int f=t[x].f,gf=t[f].f,lr=Witch(x);
        t[x].f=gf;if (Check_Root(f)) t[gf].c[Witch(f)]=x;
        t[f].c[lr]=t[x].c[lr^1];if (t[f].c[lr]) t[t[f].c[lr]].f=f;
        t[t[x].c[lr^1]=f].f=x;
        Update(f);
    }
    
    void Splay(int x) {
        int y=x;stk[++top]=y;
        for (;Check_Root(y);y=t[y].f) stk[++top]=t[y].f;
        for (;top;Pushdown(stk[top--]));
        for (;Check_Root(x);Rotate(x))
            if (Check_Root(t[x].f)) Rotate(Witch(x)!=Witch(t[x].f)?x:t[x].f);
        Update(x);
    }
    
    void Access(int x) {for (int y=0;x;x=t[y=x].f) Splay(x),t[x].c[1]=y,Update(x);}
    
    void Make_Root(int x) {Access(x);Splay(x);Reverse(x);}
    
    int Get_Root(int x) {
        Make_Root(x);Splay(x);
        while (t[x].c[0]) x=t[x].c[0],Pushdown(x);
        Splay(x);return x;
    }
    
    void Split(int x,int y) {Make_Root(x);Access(y);Splay(y);}
    
    void Link(int x,int y) {Make_Root(x);if (Get_Root(y)!=x) t[x].f=y;}
    
    void Cut(int x,int y) {Split(x,y);if (t[y].c[0]==x) t[x].f=t[y].c[0]=0,Update(y);}
    
    int main() {
        scanf("%d",&n);
        for (int i=1,x;i<=n;i++) {
            scanf("%d",&x);
            v[i]=min(i+x,n+1);
            Link(i,v[i]);
        }
        scanf("%d",&m);
        for (int i=1;i<=m;i++) {
            int order,x,y;
            scanf("%d",&order);
            switch (order) {
                case 1:{
                    scanf("%d",&x);x++;
                    Split(x,n+1);printf("%d
    ",t[n+1].s-1);
                    break;
                }
                case 2:{
                    scanf("%d%d",&x,&y);x++;
                    if (v[x]==min(x+y,n+1)) continue;
                    Cut(x,v[x]);Link(x,v[x]=min(x+y,n+1));
                    break;
                }
            }
        }
    }
    View Code
  • 相关阅读:
    Flask【第11篇】:整合Flask中的目录结构
    GIMP简介
    java 二进制数字符串转换工具类
    Linux nohup 命令
    Linux & 命令
    linux 下检查java jar包 程序是否正常 shell
    linux 下启动java jar包 shell
    linux 下停止java jar包 shell
    shell 中的特殊变量
    maven settings 配置文件
  • 原文地址:https://www.cnblogs.com/mastervan/p/11324880.html
Copyright © 2011-2022 走看看