BZOJ 3282 Tree(LCT)

【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=3282

【题目大意】

  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。

【题解】

  LCT练习题

【代码】

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=300010;
namespace Link_Cut_Tree{
    int f[N],son[N][2],val[N],sum[N],tmp[N],Xor[N];bool rev[N];
    void Initialize(){
        memset(f,0,sizeof(f));
        memset(son,0,sizeof(son));
        memset(val,0,sizeof(val));
        memset(rev,0,sizeof(rev));
        memset(sum,0,sizeof(sum));
        memset(Xor,0,sizeof(Xor));
    }
    bool isroot(int x){return !f[x]||son[f[x]][0]!=x&&son[f[x]][1]!=x;}
    void rev1(int x){if(!x)return;swap(son[x][0],son[x][1]);rev[x]^=1;}
    void pb(int x){if(rev[x])rev1(son[x][0]),rev1(son[x][1]),rev[x]=0;}
    void up(int x){
        sum[x]=Xor[x]=val[x];
        if(son[x][0])sum[x]+=sum[son[x][0]];
        if(son[x][1])sum[x]+=sum[son[x][1]];
        if(son[x][0])Xor[x]^=Xor[son[x][0]];
        if(son[x][1])Xor[x]^=Xor[son[x][1]];
    }
    void rotate(int x){
        int y=f[x],w=son[y][1]==x;
        son[y][w]=son[x][w^1];
        if(son[x][w^1])f[son[x][w^1]]=y;
        if(f[y]){
            int z=f[y];
            if(son[z][0]==y)son[z][0]=x;else if(son[z][1]==y)son[z][1]=x;
        }f[x]=f[y];f[y]=x;son[x][w^1]=y;up(y);
    }
    void splay(int x){
        int s=1,i=x,y;tmp[1]=i;
        while(!isroot(i))tmp[++s]=i=f[i];
        while(s)pb(tmp[s--]);
        while(!isroot(x)){
            y=f[x];
            if(!isroot(y)){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
            rotate(x);
        }up(x);
    }
    void access(int x){for(int y=0;x;y=x,x=f[x])splay(x),son[x][1]=y,up(x);}
    // 查询x所在的树的根
    int root(int x){access(x);splay(x);while(son[x][0])x=son[x][0];return x;}
    // 使x成为根
    void makeroot(int x){access(x);splay(x);rev1(x);}
    // 将x和y所属树合并
    void link(int x,int y){makeroot(x);f[x]=y;access(x);}
    // 将x和其父节点分开
    void cutf(int x){access(x);splay(x);f[son[x][0]]=0;son[x][0]=0;up(x);}
    // 将边x-y切断
    void cut(int x,int y){makeroot(x);cutf(y);}
    // 查询x到y的链和
    int ask(int x,int y){makeroot(x);access(y);splay(y);return sum[y];}
    // 计算x到y的xor和
    int xorsum(int x,int y){makeroot(x);access(y);splay(y);return Xor[y];}
    // 查询节点到根的距离
    int query(int x){access(x);splay(x);return sum[x];}
    // 将x为下标的值改为y
    int change(int x,int y){makeroot(x);val[x]=y;up(x);}
    // 将x的父亲改为y
    int changef(int x,int y){cutf(x);f[x]=y;}
}
int op,n,m,x,y;
int main(){
    scanf("%d%d",&n,&m);
    using namespace Link_Cut_Tree;
    Initialize();
    for(int i=1;i<=n;i++)scanf("%d",&val[i]),Xor[i]=sum[i]=val[i];
    while(m--){
        scanf("%d%d%d",&op,&x,&y);
        if(op==0)printf("%d\n",xorsum(x,y));
        else if(op==1){if(root(x)!=root(y))link(x,y);}
        else if(op==2){if(root(x)==root(y))cut(x,y);}
        else change(x,y);
    }return 0;
}
时间: 2024-10-31 17:12:39

BZOJ 3282 Tree(LCT)的相关文章

3282: Tree(LCT)

3282: Tree Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 2249  Solved: 1042[Submit][Status][Discuss] Description 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的. 1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接.

[BZOJ 3282] Tree 【LCT】

题目链接:BZOJ - 3282 题目分析 这道题是裸的LCT,包含 Link , Cut 和询问两点之间的路径信息. 写代码时出现的错误:Access(x) 的循环中应该切断的是原来的 Son[x][1] ,然而我写成了 Son[x][0] ! 代码 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <cmath> #incl

BZOJ 3282 Tree Link-Cut-Tree(LCT)

题目大意: 给定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. 只有会员才知道的世界...有个会员的大神真好 LCT的入门题,切完2631之后这个就

【BZOJ2631】tree (LCT)

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2631 终于学了LCT惹qwq (看的板是黄学长的orzzz T了很久发现窝开了个ch[MaxN][0] ,这都能编译过? 1 #include <cstdio> 2 #include <cstdlib> 3 #include <iostream> 4 #include <algorithm> 5 #define mod 51061 6 #define M

LuoguP3690 【模板】Link Cut Tree (LCT)

勉强算是结了个大坑吧或者才开始 #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a)) #define nR(a,b,c) for(register int a = (b); (a) &

【BZOJ】2002: [Hnoi2010]Bounce 弹飞绵羊(lct)

(BZOJ挂了,还没在BZOJ测,先是在wikioi测过了,,) 囧.在军训时立志要学lct!!!这是一道lct的裸题,只有access操作(10行都没有啊亲...缩行大法的话,我就不说了..)(link操作相当于水过),其实lct很简单..想想都有点小激动...... lct用splay维护的话,一下就写好了..但是我在写lct的时候,发现了一些我原来splay的老问题,我原来也知道了的,就是将null的ch给赋值了,因为在rot操作里没有特判,所以导致了null的孩子被赋值了,导致我的lct

从ZOJ2114(Transportation Network)到Link-cut-tree(LCT)

[首先声明:LCT≠动态树,前者是一种数据结构,而后者是一类问题,即:LCT—解决—>动态树] Link-cut-tree(下文统称LCT)是一种强大的数据结构,不仅可以像树链剖分一样对树上的两点进行询问(权值和.权值的最值……),还可以维护森林的连通性. 学习LCT首推杨哲神犇的<QTREE解法的一些研究>,很详细地解释了LCT的概念及实现 本文则以ZOJ2114一题为例,分析LCT实现过程中的一些事项,并且力求读者对LCT有一个“不次于‘感性’的认识” 叙述过程中会直接引用论文中的术

2014 Multi-University Training Contest 6 Apple Tree(数学题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4925 Apple Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 176    Accepted Submission(s): 120 Problem Description I've bought an orchard an

BZOJ 1997 Planar(2-SAT)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1997 题意:给出一个无向图.已知该图存在一个包含n个顶点的哈密顿回路.判定该图是不是平面图. 思路:圈将面分成内外两部分,则两条边同时在内部相交则同时在外部也是相交的.因此,必然是一个在内部一个在外部.据此建立2-SAT.平面图的边数小于等于三倍点数减六 int a[N],b[N],n,m,c[N]; int d[N],f[N]; vector<int> g[2000]; void