AC日记——【模板】Link Cut Tree 洛谷 P3690

【模板】Link Cut Tree

思路:

  LCT模板;

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxn 300005
int n,m,val[maxn];
int top,ch[maxn][2],f[maxn],xr[maxn],q[maxn],rev[maxn];
inline void in(int &now)
{
    int if_z=1;now=0;
    char Cget=getchar();
    while(Cget>‘9‘||Cget<‘0‘)
    {
        if(Cget==‘-‘) if_z=-1;
        Cget=getchar();
    }
    while(Cget>=‘0‘&&Cget<=‘9‘)
    {
        now=now*10+Cget-‘0‘;
        Cget=getchar();
    }
    now*=if_z;
}
inline void updata(int now)
{
    xr[now]=xr[ch[now][0]]^xr[ch[now][1]]^val[now];
}
inline void downdata(int now)
{
    int l=ch[now][0],r=ch[now][1];
    if(rev[now])
    {
        rev[l]^=1,rev[r]^=1,rev[now]^=1;
        swap(ch[now][0],ch[now][1]);
    }
}
inline bool isroot(int now)
{
    return ch[f[now]][0]!=now&&ch[f[now]][1]!=now;
}
inline void rotate(int now)
{
    int fa=f[now],ffa=f[fa],l,r;
    if(ch[fa][0]==now) l=0;else l=1;r=l^1;
    if(!isroot(fa))
    {
        if(ch[ffa][0]==fa) ch[ffa][0]=now;
        else ch[ffa][1]=now;
    }
    f[now]=ffa,f[fa]=now,f[ch[now][r]]=fa;
    ch[fa][l]=ch[now][r],ch[now][r]=fa;
    updata(fa),updata(now);
}
inline void splay(int now)
{
    top=1,q[top]=now;
    for(int i=now;!isroot(i);i=f[i]) q[++top]=f[i];
    for(int i=top;i;i--) downdata(q[i]);
    while(!isroot(now))
    {
        int fa=f[now],ffa=f[fa];
        if(!isroot(fa))
        {
            if((ch[fa][0]==now)^(ch[ffa][0]==fa)) rotate(now);
            else rotate(fa);
        }
        rotate(now);
    }
}
void access(int now)
{
    for(int t=0;now;t=now,now=f[now])
    {
        splay(now);
        ch[now][1]=t;
        updata(now);
    }
}
void makeroot(int now)
{
    access(now);
    splay(now);
    rev[now]^=1;
}
int find(int now)
{
    access(now);
    splay(now);
    while(ch[now][0]) now=ch[now][0];
    return now;
}
void split(int x,int y)
{
    makeroot(x);
    access(y);
    splay(y);
}
void cut(int x,int y)
{
    split(x,y);
    if(ch[y][0]==x) ch[y][0]=0,f[x]=0;
}
void link(int x,int y)
{
    makeroot(x);
    f[x]=y;
}
int main()
{
    in(n),in(m);int op,x,y,xx,yy;
    for(int i=1;i<=n;i++) in(val[i]),xr[i]=val[i];
    while(m--)
    {
        in(op);
        if(op==0)
        {
            in(x),in(y),split(x,y);
            printf("%d\n",xr[y]);
        }
        if(op==1)
        {
            in(x),in(y),xx=find(x),yy=find(y);
            if(xx!=yy) link(x,y);
        }
        if(op==2)
        {
            in(x),in(y),xx=find(x),yy=find(y);
            if(xx==yy) cut(x,y);
        }
        if(op==3)
        {
            in(x),in(y);
            access(x);
            splay(x);
            val[x]=y;
            updata(x);
        }
    }
}
时间: 2024-11-22 23:27:31

AC日记——【模板】Link Cut Tree 洛谷 P3690的相关文章

[模板]Link Cut Tree

传送门 Description 给定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. Solution \(Link\ Cut\ Tree\)模板题

AC日记——小A的糖果 洛谷七月月赛

小A的糖果 思路: for循环贪心: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #define ll long long ll ai[maxn],n,m,ans; inline void in(ll &now) { char Cget=getchar();now=0; while(Cget>'9'||Cget<'0')Cget=getchar(); while(Cget>

AC日记——无线网络发射器选址 洛谷 P2038

题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形成的网格状,并且相邻的平行街道之间的距离都是恒定值 1 .东西向街道从北到南依次编号为0,1,2…128 , 南北向街道从西到东依次编号为0,1,2…128 . 东西向街道和南北向街道相交形成路口,规定编号为x 的南北向街道和编号为y 的东西向街道形成的路口的坐标是(x , y ). 在 某 些 路口存在一定数量的公共

AC日记——红色的幻想乡 洛谷 P3801

红色的幻想乡 思路: 线段树+容斥原理: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #define maxm maxn<<2 #define ll long long class TreeType { private: int L[maxm],R[maxm],mid[maxm],dis[maxm]; public: void build(int now,int l,int r) { L

AC日记——妖梦斩木棒 洛谷 P3797

妖梦斩木棒 思路: 略坑爹: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 200005 #define maxm maxn<<2 int n,m,L[maxm],R[maxm],mid[maxm],dis[maxm]; bool xx[maxm],ll[maxm],rr[maxm]; struct AnsType { int dis; bool l,r,x; }; inline void in(int

AC日记——矩阵取数游戏 洛谷 P1005

矩阵取数游戏 思路: dp+高精: 代码: #include <bits/stdc++.h> using namespace std; #define ll long long struct Int { int len; char ai[300]; Int() { len=1,ai[0]=0; } void Count(int pos) { len++; if(pos/10) Count(pos/10); } void operator=(int pos_) { int pos=pos_; l

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

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. 输入输出

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

P3690 [模板]Link Cut Tree (动态树) https://www.luogu.org/problemnew/show/P3690 分析: LCT模板 代码: 注意一下cut! 1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace std; 5 6 const int N = 300100; 7 8 int val[N],fa[N],ch[N][2],rev[N],sum[N],st[N],top;

Codeforces Round #339 (Div. 2) A. Link/Cut Tree

A. Link/Cut Tree Programmer Rostislav got seriously interested in the Link/Cut Tree data structure, which is based on Splay trees. Specifically, he is now studying the expose procedure. Unfortunately, Rostislav is unable to understand the definition