首页 > 其他分享 >动态树(Link-Cut Tree)

动态树(Link-Cut Tree)

时间:2023-10-12 21:34:11浏览次数:46  
标签:ch int Tree 算法 Cut Link 动态 getchar

算法思想

动态树算法用于解决一类树上问题,涉及树边的连接和断开,并借助splay实现高效维护树上路径信息。算法细节见YangZhe的论文

代码实现

P3690 【模板】动态树(LCT)

#include<bits/stdc++.h>

#define ll long long
#define il inline 

using namespace std;

int read(){
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
    return x*f;
}

const int N=1e5+10;

struct Link_Cut_Tree{
    int f[N],ch[N][2],sum[N],val[N],rev[N],stk[N];
    il bool notroot(int x){
        return (ch[f[x]][0]==x)||(ch[f[x]][1]==x);
    }
    il void pushup(int x){
        sum[x]=sum[ch[x][0]]^sum[ch[x][1]]^val[x];
    }
    il void pushrev(int x){
        swap(ch[x][0],ch[x][1]);
        rev[x]^=1;
    }
    il void pushdown(int x){
        if(rev[x]){
            if(ch[x][0]) pushrev(ch[x][0]);
            if(ch[x][1]) pushrev(ch[x][1]);
            rev[x]=0;
        }
    }
    il void rotate(int x){
        int y=f[x],z=f[y];
        int d=ch[y][1]==x,w=ch[x][d^1];
        if(notroot(y)) ch[z][ch[z][1]==y]=x;ch[x][d^1]=y;ch[y][d]=w;
        if(w) f[w]=y;f[y]=x;f[x]=z;
        pushup(y);pushup(x);
    }
    il void splay(int x){
        int u=x,top=0;
        while(notroot(u)) stk[++top]=u=f[u];
        while(top) pushdown(stk[top--]);
        while(notroot(x)){
            int y=f[x],z=f[y];
            if(notroot(y)) (ch[z][0]==y)^(ch[y][0]==x)?rotate(x):rotate(y);
            rotate(x);
        }
    }
    il void access(int x){
        for(int y=0;x;x=f[y=x]){
            splay(x);ch[x][1]=y;pushup(x);
        }
    }
    il void makeroot(int x){
        access(x);splay(x);pushrev(x);
    }
    il int findroot(int x){
        access(x);splay(x);
        while(ch[x][0]) pushdown(x),x=ch[x][0];
        splay(x);
        return x;

    }
    il void split(int x,int y){
        makeroot(x);access(y);splay(y);
    }
    il void link(int x,int y){
        makeroot(x);
        if(findroot(y)!=x) f[x]=y;
    }
    il void cut(int x,int y){
        makeroot(x);
        if(findroot(y)==x&&f[y]==x&&!ch[y][0]){
            f[y]=ch[x][1]=0;
            pushup(x);
        }
    }
} lct;

int n,m;

int main(){
    n=read();m=read();
    for(int i=1;i<=n;i++){
        int x=read();
        lct.val[i]=lct.sum[i]=x;
    }
    for(int i=1;i<=m;i++){
        int op=read(),x=read(),y=read();
        if(op==0){
            lct.split(x,y);
            printf("%d\n",lct.sum[y]);
        }
        if(op==1){
            lct.link(x,y);
        }
        if(op==2){
            lct.cut(x,y);
        }
        if(op==3){
            lct.splay(x);
            lct.sum[x]^=lct.val[x]^y;
            lct.val[x]=y;
        }
    }
    return 0;
}

标签:ch,int,Tree,算法,Cut,Link,动态,getchar
From: https://www.cnblogs.com/imyhy/p/17760624.html

相关文章

  • jlink与jtag的关系
    JTAG和J-Link是两个在ARM调试和测试中有关系的工具。JTAG是一种硬件协议和标准测试协议,用于芯片内部测试,多数的高级器件都支持JTAG协议,如DSP、FPGA器件等。在ARM架构中,JTAG被用于进行硬件调试和测试,它有四个主要引脚:TMS、TCK、TDI和TDO,分别用于模式选择、时钟、数据输入和数据输......
  • 【前端小技巧】如何使用 Eolink Apilkit 调用 Mock ?
    在开发过程中,进度比较赶的情况下,前端人员当页面写完时,后台的接口还没写完,等要交付的时候后端才把接口给你,这个时候就很尴尬。这个时候Mock就可以很好的解决这个问题,前端团队可以在API还没开发完成的情况下,借助MockAPI实现预对接,加速开发进程。测试团队可以通过MockAPI解......
  • simulink中调用python脚本
      command='test.py&';%后轴&:等待调用结束(command='test.py';%无后轴&:立即执行下一句[status,cmdout]=system(command,'-echo');    参考:详解MATLAB的函数system()和shell转义字符“感叹号”,并利用它们实现在MATLAB中运行(调用)外部exe程序_matlabsy......
  • 【前端小技巧】如何使用 Eolink Apilkit 调用 Mock ?
    在开发过程中,进度比较赶的情况下,前端人员当页面写完时,后台的接口还没写完,等要交付的时候后端才把接口给你,这个时候就很尴尬。这个时候Mock就可以很好的解决这个问题,前端团队可以在API还没开发完成的情况下,借助MockAPI实现预对接,加速开发进程。测试团队可以通过MockAPI......
  • 数据库解决获取一个字段parent中某个字符串child第一次和第二次出现的位置之间的内容c
    下面就postgresql数据和oracle数据库分别提供两种解决方法--postgresql数据库解决获取一个字段parent中某个字符串child第一次和第二次出现的位置之间的内容cut--方法一selectcasewhenposition(childinparent)>0thensubstring(parent,position(childinparent)+l......
  • nodejs xxl-job-executor 客户端试用
    代码fork自awesomeoxc/xxl-job-executor-nodejs,进行了一些以来包的升级,同时发布npm包到npm仓库中,方便使用npm包名称npm包我已经发布npm仓库中了,可以直接使用@dalongrong/xxl-job-executor参考使用安装npminstall@dalongrong/xxl-job-executor--saveor......
  • router-link:导航链接 / 声明式导航
    vue-router提供了一个全局组件router-link(取代a标签)router-link本质还是a标签router-link功能:①能跳转,配置to属性指定路径(必须),本质还是a标签,to无需#②能高亮,默认就会提供高亮类名,可以直接设置高亮样式 router-link会自动给当前导航添加两个类名:router-li......
  • flink优化
    1、时间定义、事件时间和处理时间https://nightlies.apache.org/flink/flink-docs-release-1.17/docs/dev/table/concepts/time_attributes/#defining-in-ddl-12、自定义函数https://nightlies.apache.org/flink/flink-docs-release-1.17/docs/dev/table/functions/udfs......
  • 【接口测试】如何在 Eolink Apilkit 中使用 cookie ?
    什么是Cookie?Cookie是一种在网站之间传递的小型文本文件,用于存储用户的个人信息和偏好设置。当您访问一个网站时,网站会将Cookie存储在您的浏览器中,并在您下次访问该网站时读取该Cookie。这样,网站可以记住您的登录状态、购物车内容以及其他个性化设置。在编写接口自动化测试用......
  • [gym103860D]Tree Partition
    D-TreePartition考虑将树转换到一个序列上,钦定\(1\)为根节点,\(1\)的父亲为\(0\),在序列上,孩子向父亲连边然后考虑设\(dp\)状态\(dp[i][j]\)表示前\(i\)个点,分成\(j\)段的方案数,那么\(dp[i][j]\)从\(dp[k][j-1]\)转移过来要满足以下条件之一:点\(i\)的后向边\((a,b)\)满足\(a\l......