zoukankan      html  css  js  c++  java
  • [bzoj3282]Tree (lct)

    昨天看了一天的lct。。当然幸好最后看懂了(也许吧。。)

    论善良学长的重要性T_T,老司机带带我!

    这题主要是删边的时候还要判断一下。。蒟蒻一开始天真的以为存在的边才能删结果吃了一发wa。。。

    事实是只要两个点之间联通就能断开了,管它有没有边。。。。整个就一模板题。。

    交上去后跑得很慢(记录类型的锅)。。但还是很短?(请自行无视过长变量名)

     1 #include<cstdio>
     2 #include<math.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn=300233;
     7 struct zs{
     8     int c[2],fa,val,sum;
     9     bool rev;
    10 }tree[maxn];
    11 int i,j,n,m,id,x,y;
    12 int stack[maxn];
    13 inline void update(int x){tree[x].sum=tree[tree[x].c[0]].sum^tree[x].val^tree[tree[x].c[1]].sum;
    14 }
    15 inline bool isroot(int x){return tree[tree[x].fa].c[0]!=x&&tree[tree[x].fa].c[1]!=x;
    16 }
    17 void rotate(int x){
    18     int fa=tree[x].fa,gfa=tree[fa].fa;
    19     if(!isroot(fa))tree[gfa].c[tree[gfa].c[1]==fa]=x;
    20     int l=tree[fa].c[1]==x,r=l^1;
    21     tree[fa].c[l]=tree[x].c[r];tree[x].c[r]=fa;
    22     tree[fa].fa=x;tree[x].fa=gfa;tree[tree[fa].c[l]].fa=fa;
    23     update(fa);update(x);
    24 }
    25 void pushdown(int x){
    26     if(!tree[x].rev)return;
    27     int l=tree[x].c[0],r=tree[x].c[1];
    28     if(l)tree[l].rev^=1;if(r)tree[r].rev^=1;
    29     swap(tree[x].c[0],tree[x].c[1]);tree[x].rev^=1;
    30 }
    31 void splay(int x){
    32     int top=0,tmp=x;stack[++top]=x;
    33     while(!isroot(tmp))stack[++top]=tree[tmp].fa,tmp=tree[tmp].fa;
    34     while(top)pushdown(stack[top]),top--;
    35     int fa,gfa;
    36     while(!isroot(x)){
    37         fa=tree[x].fa,gfa=tree[fa].fa;
    38         if(!isroot(fa))
    39             if((tree[gfa].c[0]==fa)^(tree[fa].c[0]==x))rotate(x);
    40             else rotate(fa);
    41         rotate(x);
    42     }
    43 }
    44 void access(int x){
    45     int son=0;
    46     while(x){
    47         splay(x);tree[x].c[1]=son;
    48         update(x);
    49         son=x;x=tree[x].fa;
    50     }
    51 }
    52 void makeroot(int x){
    53     access(x);splay(x);tree[x].rev^=1;
    54 }
    55 void link(int x,int y){
    56     makeroot(x);tree[x].fa=y;splay(x);
    57 }
    58 void cut(int x,int y){
    59     makeroot(x);access(y);splay(y);tree[y].c[0]=tree[x].fa=0;
    60 }
    61 int query(int x,int y){
    62     makeroot(x);access(y);splay(y);return tree[y].sum;
    63 }
    64 int getfa(int x){
    65     access(x);splay(x);while(tree[x].c[0])pushdown(x),x=tree[x].c[0];splay(x);
    66     return x;
    67 }
    68 void change(int x,int y){
    69     makeroot(x);tree[x].val=y;update(x);
    70 }
    71 int main(){
    72     scanf("%d%d",&n,&m);
    73     for(i=1;i<=n;i++)scanf("%d",&tree[i].val),tree[i].sum=tree[i].val;
    74     while(m--){
    75         scanf("%d%d%d",&id,&x,&y);
    76         if(id==0)printf("%d
    ",query(x,y));
    77         else if(id==1){if(getfa(x)!=getfa(y))link(x,y);}
    78         else if(id==2){if(getfa(x)==getfa(y))cut(x,y);}
    79         else if(id==3)change(x,y);
    80     }
    81     return 0;
    82 }
    View Code

    b站上的lct怎么都是300大洋的世界。。

     16.1.13:重写了一发

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=300233;
     6 int ch[maxn][2],fa[maxn],sum[maxn],num[maxn],st[maxn];
     7 bool rev[maxn];
     8 int i,j,n,m,x,y;
     9 
    10 int ra;char rx;
    11 inline int read(){
    12     rx=getchar(),ra=0;
    13     while(rx<'0'||rx>'9')rx=getchar();
    14     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    15 }
    16 char s[11];
    17 inline void outx(int x){
    18     if(!x)putchar('0');
    19     register int len=0;
    20     while(x)s[++len]=x%10,x/=10;
    21     while(len)putchar(s[len--]+48);putchar('
    ');
    22 }
    23 inline bool isrt(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
    24 inline void upd(int x){sum[x]=sum[ch[x][0]]^num[x]^sum[ch[x][1]];}
    25 inline void pushdown(int x){
    26     if(!rev[x])return;
    27     rev[x]=0,swap(ch[x][0],ch[x][1]),rev[ch[x][0]]^=1,rev[ch[x][1]]^=1;
    28 }
    29 inline void rotate(int x){
    30     int f=fa[x],gfa=fa[f],l=ch[f][1]==x,r=l^1;
    31     if(!isrt(f))ch[gfa][ch[gfa][1]==f]=x;
    32     fa[x]=gfa,fa[f]=x,ch[f][l]=ch[x][r],ch[x][r]=f,fa[ch[f][l]]=f;
    33     sum[x]=sum[f],upd(f);
    34 }
    35 void splay(int x){
    36     int f,gfa;
    37     for(st[st[0]=1]=f=x;!isrt(f);)st[++st[0]]=(f=fa[f]);
    38     while(st[0])pushdown(st[st[0]--]);
    39     for(f=fa[x],gfa=fa[f];!isrt(x);rotate(x),f=fa[x],gfa=fa[f])
    40         if(!isrt(f))rotate(((ch[f][0]==x)^(ch[gfa][0]==f))?x:f);
    41 }
    42 inline void access(int x){
    43     for(int t=0;x;t=x,x=fa[x])splay(x),ch[x][1]=t,upd(x);
    44 }
    45 inline void makert(int x){
    46     access(x),splay(x),rev[x]^=1;
    47 }
    48 void cut(int x,int y){
    49     makert(x),access(y),splay(y),ch[y][0]=fa[x]=0,upd(y);
    50 }
    51 void link(int x,int y){
    52     makert(x),fa[x]=y;if(!(x&233))splay(x);
    53 }
    54 inline int query(int x,int y){
    55     makert(x),access(y),splay(y);
    56     return sum[y];
    57 }
    58 inline int getfa(int x){
    59     for(access(x),splay(x),pushdown(x);ch[x][0];x=ch[x][0]);
    60     return x;
    61 }
    62 inline void change(int x,int v){
    63     splay(x),num[x]=v,upd(x);
    64 }
    65 int main(){
    66     n=read(),m=read();
    67     for(i=1;i<=n;i++)num[i]=read();int id;
    68     while(m--){
    69         id=read(),x=read(),y=read();
    70         if(id==0)outx(query(x,y));
    71         if(id==1)if(getfa(x)!=getfa(y))link(x,y);
    72         if(id==2)if(getfa(x)==getfa(y))cut(x,y);
    73         if(id==3)change(x,y);
    74     }
    75     return 0;
    76 }
    View Code

    3282: Tree

    Time Limit: 30 Sec  Memory Limit: 512 MB

    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。

    Input

    第1行两个整数,分别为N和M,代表点数和操作数。

    第2行到第N+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。

    第N+2行到第N+M+1行,每行三个整数,分别代表操作类型和操作所需的量。

     

    Output

    对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。

    Sample Input

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

    Sample Output

    3
    1
     

    HINT

    1<=N,M<=300000

  • 相关阅读:
    kbmMW RunInTransaction
    有感Delphi 2021路线图
    kbmMW 5.13.00 Scheduler不执行SynchronizedAfterRun
    Delphi 10.4.1的编译器bug终于修正了!
    OUI作者开源作品
    kali安装pwntools遇到的一些问题
    电子公文传输系统团队项目
    AI 学习框架
    Linux top命令的用法详细详解
    c# DateTime时间格式和JAVA时间戳格式相互转换
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/4723225.html
Copyright © 2011-2022 走看看