zoukankan      html  css  js  c++  java
  • 洛谷 P3690 【模板】Link Cut Tree (动态树) || bzoj 3282: Tree

    https://blog.csdn.net/saramanda/article/details/55253627

    https://blog.csdn.net/CHHNZ/article/details/55504875

    lct模板

      1 #include<cstdio>
      2 #include<algorithm>
      3 using namespace std;
      4 namespace LCT
      5 {
      6 struct Node
      7 {
      8     Node *ch[2],*fa;
      9     bool rev;
     10     int dat,xorx;
     11 }nodes[300100];
     12 int mem;
     13 Node *getnode()
     14 {
     15     return nodes+(mem++);
     16 }
     17 bool isroot(Node *x)
     18 {
     19     return (!x->fa)||((x->fa->ch[0]!=x)&&(x->fa->ch[1]!=x));
     20 }
     21 void upd(Node *x)
     22 {
     23     x->xorx=(x->ch[0]?x->ch[0]->xorx:0)^(x->ch[1]?x->ch[1]->xorx:0)^x->dat;
     24 }
     25 void pd(Node *x)
     26 {
     27     if(x->rev)
     28     {
     29         swap(x->ch[0],x->ch[1]);
     30         if(x->ch[0])    x->ch[0]->rev^=1;
     31         if(x->ch[1])    x->ch[1]->rev^=1;
     32         x->rev=0;
     33     }
     34 }
     35 bool gson(Node *o)    {return o==o->fa->ch[1];}//获得是父亲的左儿子(返回0)还是右儿子(1),要求保证存在父亲
     36 void rotate(Node *o,bool d)
     37 //在o子树中执行d=0左旋,d=1右旋,在旋转前不标记下传,并将o父节点的对应子节点由o变为需要值,要求保证存在子树(!d)
     38 {
     39     Node *k=o->ch[!d];if(!isroot(o))    o->fa->ch[gson(o)]=k;//注意这一句修改o父节点的要写在前面,曾经出过错调了一会
     40     o->ch[!d]=k->ch[d];k->ch[d]=o;
     41     upd(o);upd(k);
     42     k->fa=o->fa;o->fa=k;if(o->ch[!d])    o->ch[!d]->fa=o;
     43 }
     44 Node *st[300100];int top;
     45 void solvetag(Node *o)
     46 {
     47     while(!isroot(o))    st[++top]=o,o=o->fa;
     48     st[++top]=o;
     49     while(top)    pd(st[top--]);
     50 }
     51 void splay(Node *o)
     52 {
     53     solvetag(o);
     54     Node *fa,*fafa;bool d1,d2;
     55     while(!isroot(o))
     56     {
     57         fa=o->fa;d1=(o==fa->ch[0]);
     58         if(isroot(fa))    rotate(fa,d1);
     59         else
     60         {
     61             fafa=o->fa->fa;d2=(fa==fafa->ch[0]);//要保证fa不是root之后才能获取这两个值,曾错过
     62             if(d1==d2)    rotate(fafa,d1),rotate(fa,d1);//zig-zig,两次相同方向的单旋,先把父亲转上去,再把自己转上去
     63             else    rotate(fa,d1),rotate(fafa,d2);//zig-zag,两次相反方向的单旋,连续两次把自己转上去
     64         }
     65     }
     66 }
     67 void access(Node *o)
     68 {
     69     for(Node *lst=NULL;o;lst=o,o=o->fa)
     70     {
     71         splay(o);//此处不pushdown是由于splay中保证进行过了
     72         o->ch[1]=lst;upd(o);//注意upd
     73     }
     74 }
     75 Node *gtop(Node *o)
     76 {
     77     access(o);splay(o);
     78     for(;o->ch[0];o=o->ch[0],pd(o));//此处不在开始前pushdown(o)是由于splay中保证进行过了
     79     splay(o);return o;//听说这里不splay一下也很难卡掉
     80 }
     81 void mtop(Node *o)    {access(o);splay(o);o->rev^=1;}
     82 void link(Node *x,Node *y)
     83 {
     84     if(gtop(x)==gtop(y))    return;
     85     mtop(y);y->fa=x;
     86 }
     87 void cut(Node *x,Node *y)
     88 {
     89     mtop(x);access(y);splay(y);
     90     if(y->ch[0]!=x||x->ch[1])    return;//如果x、y之间直接有边,那么上面一行的操作之后应当是x与y在单独一棵splay中,那么一定保证y左子节点是x且x没有右子节点
     91     x->fa=y->ch[0]=NULL;//注意,改的是x的父亲和y的子节点(虽然x的确是树的根,但是此时在splay上是y的子节点,不能搞混)
     92     upd(y);//注意
     93 }
     94 int query(Node *x,Node *y)
     95 {
     96     mtop(x);access(y);splay(y);
     97     //if(gtop(y)!=x)    return 0;//此题保证x与y连通,不需要
     98     return y->xorx;
     99 }
    100 }
    101 LCT::Node *nd[300100];
    102 int n,m;
    103 int main()
    104 {
    105     int i,idx,x,y;
    106     scanf("%d%d",&n,&m);
    107     for(i=1;i<=n;i++)
    108     {
    109         nd[i]=LCT::getnode();
    110         scanf("%d",&nd[i]->dat);nd[i]->xorx=nd[i]->dat;//注意改xorx
    111     }
    112     for(i=1;i<=m;i++)
    113     {
    114         scanf("%d%d%d",&idx,&x,&y);
    115         if(idx==0)    printf("%d
    ",LCT::query(nd[x],nd[y]));
    116         else if(idx==1)    LCT::link(nd[x],nd[y]);
    117         else if(idx==2)    LCT::cut(nd[x],nd[y]);
    118         else if(idx==3)    LCT::splay(nd[x]),nd[x]->dat=y,LCT::upd(nd[x]);
    119         //可能是由于题面和数据的一些奥妙重重的原因,此题即使不splay(nd[x])也可以A掉,但是splay到根之后却能保证改变该点权值只会影响自身的xorx
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    [Nginx] 解决跨域been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
    [GO项目]开源免费在线客服系统-真正免费开源-GOFLY0.3.2发布-极简强大Go语言开发网页客服
    [PHP] php使用curl_multi_exec并行同时执行http请求
    [PHP] PHP redis滑动窗口频率限制
    [PHP] xml转为数组函数
    [javascript] 全国省市县JSON/XML数据(包含台湾和海外国家一级)
    [MySQL] 注意MySQL5.1不支持utf8mb4 Error 1115: Unknown character set: 'utf8mb4'
    [Go] linux下安装go1.16
    [GO项目]开源免费在线客服系统-真正免费开源-GOFLY0.2.9发布-极简强大Go语言开发网页客服
    [PHP]PHP不支持方法重载和只支持方法覆盖
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8861395.html
Copyright © 2011-2022 走看看