• BZOJ2631: tree(LCT)


    Description

     一棵n个点的树,每个点的初始权值为1。对于这棵树有q个操作,每个操作为以下四种操作之一:
    + u v c:将u到v的路径上的点的权值都加上自然数c;
    - u1 v1 u2 v2:将树中原有的边(u1,v1)删除,加入一条新边(u2,v2),保证操作完之后仍然是一棵树;
    * u v c:将u到v的路径上的点的权值都乘上自然数c;
    / u v:询问u到v的路径上的点的权值和,求出答案对于51061的余数。

    Input

      第一行两个整数n,q
    接下来n-1行每行两个正整数u,v,描述这棵树
    接下来q行,每行描述一个操作

    Output

      对于每个/对应的答案输出一行

    Sample Input

    3 2
    1 2
    2 3
    * 1 3 4
    / 1 1

    Sample Output

    4

    解题思路:

    假如没有2操作,且图是树,是不是想起了线段树。

    这道题也是一样的道理,LCT嘛,splay维护树链

    代码:

      1 // luogu-judger-enable-o2
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define lll tr[spc].ch[0]
      6 #define rrr tr[spc].ch[1]
      7 #define ls ch[0]
      8 #define rs ch[1]
      9 typedef unsigned int lnt;
     10 const lnt mod=51061;
     11 struct trnt{
     12     int ch[2];
     13     int fa;
     14     int lzt;
     15     lnt add;
     16     lnt mul;
     17     lnt sum;
     18     lnt wgt;
     19     lnt val;
     20     bool anc;
     21 }tr[100005];
     22 int st[100001];
     23 int tp;
     24 int n,q;
     25 char cmd[10];
     26 int read()
     27 {
     28     int f=1,x=0;
     29     char ss=getchar();
     30     while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
     31     while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
     32     return f*x;
     33 }
     34 int comd(void)
     35 {
     36     if(cmd[0]=='+')
     37         return 1;
     38     if(cmd[0]=='-')
     39         return 2;
     40     if(cmd[0]=='*')
     41         return 3;
     42     if(cmd[0]=='/')
     43         return 4;
     44     return 0;
     45 }
     46 bool whc(int spc)
     47 {
     48     return tr[tr[spc].fa].rs==spc;
     49 }
     50 void pushup(int spc)
     51 {
     52     tr[spc].wgt=tr[lll].wgt+tr[rrr].wgt+1;
     53     tr[spc].sum=(tr[lll].sum+tr[rrr].sum+tr[spc].val)%mod;
     54 }
     55 void trr(int spc)
     56 {
     57     if(!spc)
     58         return ;
     59     tr[spc].lzt^=1;
     60     std::swap(lll,rrr);
     61 }
     62 void Mul(int spc,lnt k)
     63 {
     64     if(!spc)
     65         return ;
     66     tr[spc].add=tr[spc].add*k%mod;
     67     tr[spc].sum=tr[spc].sum*k%mod;
     68     tr[spc].val=tr[spc].val*k%mod;
     69     tr[spc].mul=tr[spc].mul*k%mod;
     70 }
     71 void Add(int spc,lnt k)
     72 {
     73     if(!spc)
     74         return ;
     75     if(tr[spc].mul)
     76     {
     77         Mul(lll,tr[spc].mul);
     78         Mul(rrr,tr[spc].mul);
     79         tr[spc].mul=1;
     80     }
     81     tr[spc].sum=(tr[spc].sum+tr[spc].wgt*k)%mod;
     82     tr[spc].val=(tr[spc].val+k)%mod;
     83     tr[spc].add=(tr[spc].add+k)%mod;
     84 }
     85 void pushdown(int spc)
     86 {
     87     if(tr[spc].lzt)
     88     {
     89         tr[spc].lzt=0;
     90         trr(lll);
     91         trr(rrr);
     92     }
     93     if(tr[spc].mul!=1)
     94     {
     95         Mul(lll,tr[spc].mul);
     96         Mul(rrr,tr[spc].mul);
     97         tr[spc].mul=1;
     98     }
     99     if(tr[spc].add)
    100     {
    101         Add(lll,tr[spc].add);
    102         Add(rrr,tr[spc].add);
    103         tr[spc].add=0;
    104     }
    105 }
    106 void rotate(int spc)
    107 {
    108     int f=tr[spc].fa;
    109     bool k=whc(spc);
    110     tr[f].ch[k]=tr[spc].ch[!k];
    111     tr[spc].ch[!k]=f;
    112     if(tr[f].anc)
    113     {
    114         tr[spc].anc=1;
    115         tr[f].anc=0;
    116     }else
    117         tr[tr[f].fa].ch[whc(f)]=spc;
    118     tr[spc].fa=tr[f].fa;
    119     tr[f].fa=spc;
    120     tr[tr[f].ch[k]].fa=f;
    121     pushup(f);
    122     pushup(spc);
    123 }
    124 void splay(int spc)
    125 {
    126     tp=0;
    127     int x=spc;
    128     while(!tr[x].anc)
    129         st[++tp]=x,x=tr[x].fa;
    130     st[++tp]=x;
    131     while(tp)
    132         pushdown(st[tp--]);
    133     while(!tr[spc].anc)
    134     {
    135         int ft=tr[spc].fa;
    136         if(tr[ft].anc)
    137         {
    138             rotate(spc);
    139             return ;
    140         }
    141         if(whc(spc)^whc(ft))
    142             rotate(spc);
    143         else
    144             rotate(ft);
    145         rotate(spc);
    146     }
    147     pushup(spc);
    148 }
    149 void access(int spc)
    150 {
    151     int lst=0;
    152     while(spc)
    153     {
    154         splay(spc);
    155         tr[rrr].anc=1;
    156         tr[lst].anc=0;
    157         rrr=lst;
    158         pushup(spc);
    159         lst=spc;
    160         spc=tr[spc].fa;
    161     }
    162 }
    163 void Mtr(int spc)
    164 {
    165     access(spc);
    166     splay(spc);
    167     trr(spc);
    168 }
    169 void split(int x,int y)
    170 {
    171     Mtr(x);
    172     access(y);
    173     splay(y);
    174 }
    175 void link(int x,int y)
    176 {
    177     Mtr(x);
    178     tr[x].fa=y;
    179 }
    180 void cut(int x,int y)
    181 {
    182     split(x,y);
    183     tr[y].ls=0;
    184     tr[x].fa=0;
    185     tr[x].anc=1;
    186     pushup(y);
    187 }
    188 int main()
    189 {
    190     n=read();
    191     q=read();
    192     for(int i=1;i<=n;i++)
    193     {
    194         tr[i].anc=1;
    195         tr[i].mul=1;
    196         tr[i].val=1;
    197         tr[i].wgt=tr[i].sum=1;
    198     }
    199     for(int i=1;i<n;i++)
    200     {
    201         int a=read(),b=read();
    202         link(a,b);
    203     }
    204     while(q--)
    205     {
    206         scanf("%s",cmd);
    207         int opt=comd();
    208         if(opt==1)
    209         {
    210             int u=read(),v=read(),c=read();
    211             split(u,v);
    212             Add(v,c);
    213         }
    214         if(opt==2)
    215         {
    216             int ua=read(),va=read(),ub=read(),vb=read();
    217             cut(ua,va);
    218             link(ub,vb);
    219         }
    220         if(opt==3)
    221         {
    222             int u=read(),v=read(),c=read();
    223             split(u,v);
    224             Mul(v,c);
    225         }
    226         if(opt==4)
    227         {
    228             int u=read(),v=read();
    229             split(u,v);
    230             printf("%u
    ",tr[v].sum);
    231         }
    232     }
    233     return 0;
    234 }
  • 相关阅读:
    rsync 服务器配置过程
    百度基础技术总结
    利用cobbler无人值守批量安装centos
    安装批量装机工具cobbler过程
    面试题
    JS作用域
    原型链
    ES6优缺点
    PostCSS理解与运用
    置换元素和非置换元素
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9639919.html
Copyright © 2020-2023  润新知