luogup3690模板linkcuttree(动态树)lct模板

嘒彼小星 嘒彼小星     2022-10-13     286

关键词:

P3690 【模板】Link Cut Tree (动态树)

题目背景

动态树

题目描述

给定n个点以及每个点的权值,要你处理接下来的m个操作。操作有4种。操作从0到3编号。点从1到n编号。
0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。
1:后接两个整数(x,y),代表连接x到y,若x到y已经联通则无需连接。
2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。
3:后接两个整数(x,y),代表将点x上的权值变成y。

输入输出格式

输入格式:

第1行两个整数,分别为n和m,代表点数和操作数。
第2行到第n+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。
第n+2行到第n+m+1行,每行三个整数,分别代表操作类型和操作所需的量。

输出格式:

对于每一个0号操作,你须输出x到y的路径上点权的xor和。

输入输出样例

输入样例/#1:

3 3
1
2
3
1 1 2
0 1 2
0 1 1

输出样例/#1:

3
1

说明

数据范围: (1 leq N leq 3 imes 10^5)

LCT模板题。洛谷上有点卡常。。神TM插入的时候要按顺序插。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <string> 
#include <cmath> 
#include <sstream>
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
#define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
template<class T>
inline void swap(T &a, T &b)
{
    T tmp = a;a = b;b = tmp;
}
inline void read(int &x)
{
    x = 0;char ch = getchar(), c = ch;
    while(ch < '0' || ch > '9') c = ch, ch = getchar();
    while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    if(c == '-') x = -x;
}
const int INF = 0x3f3f3f3f;
const int MAXN = 300000 + 10;
int ch[MAXN][2], fa[MAXN], data[MAXN], sum[MAXN], lazy[MAXN];
inline void pushup(int x){sum[x] = data[x] ^ sum[ch[x][0]] ^ sum[ch[x][1]];}
inline int son(int x){return x == ch[fa[x]][1];}
inline void rever(int x){lazy[x] ^= 1, swap(ch[x][0], ch[x][1]);}
inline void pushdown(int x){if(lazy[x])lazy[x] = 0, rever(ch[x][0]), rever(ch[x][1]);}
inline int isroot(int x){return ch[fa[x]][1] != x && ch[fa[x]][0] != x;}
void dfs(int x){if(x)dfs(fa[x]),pushdown(x);}
void rotate(int x)
{
    int y = fa[x], z = fa[y], b = son(x), c = son(y), a = ch[x][!b];
    if(!isroot(y) && z) ch[z][c] = x; fa[x] = z;
    if(a) fa[a] = y;ch[y][b] = a;
    ch[x][!b] = y, fa[y] = x;
    pushup(y), pushup(x);
}
void splay(int x)
{
    dfs(x);
    while(!isroot(x))
    {
        int y = fa[x], z = fa[y];
        if(!isroot(y))
            if(son(x) == son(y)) rotate(y);
            else rotate(x);
        rotate(x);
    }
}
inline void access(int x){for(int y = 0;x;y = x, x = fa[x]) splay(x), ch[x][1] = y,pushup(x);}
inline void makeroot(int x){access(x), splay(x), rever(x);}
inline int findroot(int x){access(x), splay(x);while(ch[x][0])x = ch[x][0];splay(x);return x;}
inline void link(int x, int y){makeroot(y), fa[y] = x;}
inline void path(int x, int y){makeroot(x), access(y), splay(y);}
inline void cut(int x, int y){path(x, y);if(ch[y][0] == x) fa[x] = 0, ch[y][0] = 0;pushup(y);}
int n,m,tmp1,tmp2,tmp3;
int main()
{
    read(n), read(m);
    register int i;
    for(i = 1;i + 3 <= n;i += 4) 
    {
        read(data[i]), sum[i] = data[i];
        read(data[i + 1]), sum[i + 1] = data[i + 1];
        read(data[i + 2]), sum[i + 2] = data[i + 2];
        read(data[i + 3]), sum[i + 3] = data[i + 3];
    }
    for(;i <= n;++ i) read(data[i]), sum[i] = data[i];
    for(int i = 1;i <= m;++ i)
    {
        read(tmp1), read(tmp2), read(tmp3);
        if(tmp1 == 0) path(tmp2, tmp3), printf("%d
", sum[tmp3]);
        else if(tmp1 == 1)
        {
            int f1 = findroot(tmp2), f2 = findroot(tmp3);
            if(f1 != f2) link(tmp2, tmp3);
        }
        else if(tmp1 == 2)
        {
            int f1 = findroot(tmp2), f2 = findroot(tmp3); 
            if(f1 == f2) cut(tmp2, tmp3);
        }   
        else access(tmp2), splay(tmp2), data[tmp2] = tmp3, pushup(tmp2);
    }
    return 0;
}

luogup3690模板linkcuttree(动态树)[lct]

题目背景动态树题目描述给定N个点以及每个点的权值,要你处理接下来的M个操作。操作有4种。操作从0到3编号。点从1到N编号。0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证... 查看详情

ac日记——模板linkcuttree洛谷p3690

【模板】LinkCutTree 思路:  LCT模板; 代码:#include<bits/stdc++.h>usingnamespacestd;#definemaxn300005intn,m,val[maxn];inttop,ch[maxn][2],f[maxn],xr[maxn],q[maxn],rev[maxn];inlinevoidin(int&now 查看详情

luogu3690模板linkcuttree(动态树)

题目luogu3690硫硼作者想提醒大家,WA了TLE了RE了的,也许只是主函数写错了代码#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>#include<cstdlib>#include<cstring>usingnamespacestd 查看详情

luogu3690模板linkcuttree(动态树)

参考there和there#include<iostream>#include<cstdio>usingnamespacestd;intn,m,val[300005],ch[300005][2],sum[300005],fa[300005],uu,vv,opt;intrev[300005];voidpushDown(intx)if(rev[x])swap(ch[x][0 查看详情

洛谷3690:模板linkcuttree——题解(代码片段)

https://www.luogu.org/problemnew/show/P3690给定n个点以及每个点的权值,要你处理接下来的m个操作。操作有4种。操作从0到3编号。点从1到n编号。0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。1:... 查看详情

p3690linkcuttree(动态树)

干脆整个LCT模板吧。缺个链上修改和子树操作,链上修改的话join(u,v)然后把vsplay到树根再打个标记就好。至于子树操作...以后有空的话再学(咕咕咕警告)1#include<bits/stdc++.h>2usingnamespacestd;3typedeflonglongll;4constintN=1e5+10;5intn,m,a[N],X... 查看详情

p3690模板linkcuttree(动态树)(代码片段)

哇,做梦也没想到我居然能写LCT题意:给定n个点以及每个点的权值,要你处理接下来的m个操作。操作有4种。操作从0到3编号。点从1到n编号。0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通... 查看详情

洛谷p3690模板linkcuttree(lct)(代码片段)

题目背景动态树题目描述给定n个点以及每个点的权值,要你处理接下来的m个操作。操作有4种。操作从0到3编号。点从1到n编号。0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。1:后接两... 查看详情

刷题洛谷p3690模板linkcuttree(动态树)(代码片段)

题目背景动态树题目描述给定n个点以及每个点的权值,要你处理接下来的m个操作。操作有4种。操作从0到3编号。点从1到n编号。0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。1:后接两... 查看详情

p3690模板linkcuttree(动态树)(代码片段)

P3690【模板】LinkCutTree(动态树)注意:不要把$fa[x]$和$nrt(x)$混在一起!#include<cstdio>voidswap(int&a,int&b)a^=b^=a^=b;#defineN300005intn,m,s[N],v[N],ch[2][N],fa[N],rev[N];#definelcch[0][x]#definercch[1][x]boolnrt(intx)returnch[0][fa[x]]==x||ch[1][fa[x]]==x;voidu... 查看详情

p3690模板linkcuttree(动态树)(代码片段)

LCTLCT即Link-Cut-Tree维护一个森林,支持很多操作,比如:维护链上信息(min,max,sum,xor。。。。。。)换根动态维护联通性维护子树信息概念虚边:连接儿子与父亲,儿子记录父亲,父亲不记录儿子(父不认子)实边:父子互... 查看详情

[p3690]linkcuttree(代码片段)

Description:给定n个点以及每个点的权值,要你处理接下来的m个操作。操作有4种。操作从0到3编号。点从1到n编号。0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。1:后接两个整数(x,y),代... 查看详情

数据结构专题-学习笔记:linkcuttree动态树

1.前言LinkCutTree动态树,简称LCT,是一种维护动态森林的数据结构。前置知识:Splay。2.LCT例题:P3690【模板】动态树(LinkCutTree)2.1实链剖分实链剖分也是一种对树的剖分方式,类似于重链剖分和长链剖分,其将一棵树上的边,随... 查看详情

luogup3690列队(代码片段)

https://www.luogu.org/problemnew/show/P3960作为一个初二蒟蒻要考提高组,先做一下17年的题目我们发现进行一次操作相当于把第x行的第y个弹出记为a,其余向左移=splay中弹出第y个把第m列的第x个弹出记为b,其余向上移=splay中弹出第x个把b... 查看详情

模板linkcuttree(动态树)

题目描述给定N个点以及每个点的权值,要你处理接下来的M个操作。操作有4种。操作从0到3编号。点从1到N编号。0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的... 查看详情

[模板]linkcuttree(代码片段)

...:后接两个整数(x,y),代表将点x上的权值变成y。Solution(LinkCutTree)模板题(findroot)后要(Splay)到根?不然复杂度不保证???在洛谷上实测(535ms),还算比较快吧函数变量名奇异+神仙缩行(ightarrow)还是别看了Code?//2019.1.2618:41-22:54#inclu... 查看详情

luogup3809模板后缀排序

二次联通门:luoguP3809【模板】后缀排序     /*luoguP3809【模板】后缀排序后缀数组sa表示排名为i的是第几个后缀求出sa数组后输出即可*/#include<cstdio>#include<cstring>#defineMax1000008voidread(int&now){registerch 查看详情

lct(linkcuttree)动态树(代码片段)

模板参考:https://blog.csdn.net/saramanda/article/details/55253627几个知识点:1、LCT中用Splay维护链,这些Splay叫做“辅助树“。辅助树以它上面每个节点的深度为关键字维护,就是辅助树中每个节点左儿子的深度小于当前节点的深度... 查看详情