zoukankan      html  css  js  c++  java
  • bzoj2631 tree LCT 区间修改,求和

    tree

    Time Limit: 30 Sec  Memory Limit: 128 MB
    Submit: 4962  Solved: 1697
    [Submit][Status][Discuss]

    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


    HINT

    数据规模和约定

    10%的数据保证,1<=n,q<=2000

    另外15%的数据保证,1<=n,q<=5*10^4,没有-操作,并且初始树为一条链

    另外35%的数据保证,1<=n,q<=5*10^4,没有-操作

    100%的数据保证,1<=n,q<=10^5,0<=c<=10^4

    题解:

      基本操作,可以作为模板题

      1 #include<cstring>
      2 #include<cmath>
      3 #include<algorithm>
      4 #include<iostream>
      5 #include<cstdio>
      6 
      7 #define N 100007
      8 #define ll unsigned int
      9 using namespace std;
     10 const int mod=51061;
     11 inline int read()
     12 {
     13     int x=0,f=1;char ch=getchar();
     14     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
     15     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     16     return x*f;
     17 }
     18 
     19 int n,q;
     20 ll sum[N],num[N],add[N],mul[N],rev[N],siz[N];
     21 int c[N][2],fa[N],st[N];
     22 
     23 void change(int p,ll mu,ll ad)
     24 {
     25     if (!p) return;
     26     mul[p]=mul[p]*mu%mod;
     27     add[p]=(add[p]*mu+ad)%mod;
     28     num[p]=(num[p]*mu+ad)%mod;
     29     sum[p]=(sum[p]*mu+ad*siz[p])%mod;
     30 }
     31 void update(int p)
     32 {
     33     int l=c[p][0],r=c[p][1];
     34     siz[p]=(siz[l]+siz[r]+1)%mod;
     35     sum[p]=(sum[l]+sum[r]+num[p])%mod;
     36 }
     37 void pushdown(int p)
     38 {
     39     int l=c[p][0],r=c[p][1];
     40     if (rev[p])
     41     {
     42         rev[p]^=1,rev[l]^=1,rev[r]^=1;
     43         swap(c[p][0],c[p][1]);
     44     }
     45     if (add[p]!=0||mul[p]!=1)
     46     {
     47         change(l,mul[p],add[p]);
     48         change(r,mul[p],add[p]);
     49     }
     50     add[p]=0,mul[p]=1;
     51 }
     52 inline bool isroot(int x)
     53 {
     54      return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
     55  }
     56 void rotate(int x)
     57 {
     58     int y=fa[x],z=fa[y],l,r;
     59     if (c[y][0]==x) l=0;else l=1;r=l^1;
     60     if (!isroot(y))
     61     {
     62         if (c[z][0]==y) c[z][0]=x;
     63         else c[z][1]=x;
     64     }
     65     fa[x]=z,fa[y]=x,fa[c[x][r]]=y;
     66     c[y][l]=c[x][r],c[x][r]=y;
     67     update(y),update(x);
     68 }
     69 void splay(int x)
     70 {
     71     int top=0;st[++top]=x;
     72     for (int i=x;!isroot(i);i=fa[i])
     73         st[++top]=fa[i];
     74     for (int i=top;i>=1;i--)
     75         pushdown(st[i]);
     76     while(!isroot(x))
     77     {
     78         int y=fa[x],z=fa[y];
     79         if (!isroot(y))
     80         {
     81             if (c[y][0]==x^c[z][0]==y) rotate(x);
     82             else rotate(y);
     83         }
     84         rotate(x);
     85     }
     86 }
     87 void access(int x)
     88 {
     89     int t=0;
     90     while(x)
     91     {
     92         splay(x);
     93         c[x][1]=t;
     94         update(x);
     95         t=x,x=fa[x];
     96     }
     97 }
     98 void makeroot(int x)
     99 {
    100     access(x);
    101     splay(x);
    102     rev[x]^=1;
    103 }
    104 void link(int x,int y)
    105 {
    106     makeroot(x);
    107     fa[x]=y;
    108     splay(x);
    109 }
    110 void cut(int x,int y)
    111 {
    112     makeroot(x);
    113     access(y);
    114     splay(y);
    115     fa[x]=c[y][0]=0;
    116 }
    117 int main()
    118 {
    119    // freopen("fzy.in","r",stdin);
    120 //    freopen("fzy.out","w",stdout);
    121     
    122     n=read(),q=read();
    123     for (int i=1;i<=n;i++)num[i]=sum[i]=mul[i]=siz[i]=1;
    124     for (int i=1;i<n;i++)
    125     {
    126         int u=read(),v=read();
    127         link(u,v);
    128     }
    129     for (int i=1;i<=q;i++)
    130     {
    131         char ch[2];
    132         scanf("%s",ch);
    133         switch(ch[0])
    134         {
    135             case'+':
    136             {
    137                 int u=read(),v=read();ll c=read();
    138                     makeroot(u),access(v),splay(v);
    139                     change(v,1,c);break;
    140             }
    141             case'-':
    142             {
    143                 int u1=read(),v1=read(),u2=read(),v2=read();
    144                     cut(u1,v1),link(u2,v2);break;
    145             }
    146             case'*':
    147             {
    148                 int u=read(),v=read();ll c=read();
    149                     makeroot(u),access(v),splay(v);
    150                     change(v,c,0);break;
    151             }
    152             case'/':
    153             {
    154                 int u=read(),v=read();    
    155                     makeroot(u);
    156                     access(v);
    157                     splay(v);
    158                     printf("%d
    ",sum[v]);
    159                     break;
    160             }
    161         }
    162     }
    163 }
  • 相关阅读:
    [技术讨论] [NR]请教是怎么理解SSB/RMSI/BWP的
    在TD-LTE中,应用层速率,PDCP层速率,MAC层速率,物理层速率
    5G超级上行国际标准制定 预计明年完成 来源:通信信息报
    LTE 下行PDSCH 信道功率分配-Pa、Pb
    GSM信道(控制信道和业务信道)转自搜狗百科
    10秒钟让你的日志模块化
    当Parallel遇上了DI
    Spring Boot 高效数据聚合之道
    如何用代理平台解决微服务的一些痛点
    linux守护进程、SIGHUP与nohup详解
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8119094.html
Copyright © 2011-2022 走看看