zoukankan      html  css  js  c++  java
  • [洛谷P1501] [国家集训队] Tree II

    比之前那道LCT裸题难了一点儿。

    题目传送门

    这道题除了维护树的形态和连通性,还要维护点权了。

    所以记录size、sum什么的,跟splay差不多。

    lazy_tag、pushup、pushdown什么的,跟线段树差不多。

    就是一道大杂烩嘛......

    各种乱搞。

    这里不再写cut(x,y)函数了,而是写了isolate(x,y)函数。

    意为把从x到y的链单独提取到一个splay里面。

    再加个删除父子关系不就是cut了嘛。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define M 51061
      5 #define ll long long
      6 #define id(x) (s[f[x]][1]==x)
      7 using namespace std;
      8 
      9 int n,q;
     10 int s[100005][2],f[100005],sz[100005];
     11 bool rev[100005],rt[100005];
     12 ll v[100005],sum[100005],lza[100005],lzm[100005];
     13 
     14 void reverse(int p)
     15 {
     16     if(!p)return;
     17     swap(s[p][0],s[p][1]);
     18     rev[p]^=1;
     19 }
     20 
     21 void pushup(int p)
     22 {
     23     sz[p]=sz[s[p][0]]+sz[s[p][1]]+1;
     24     sum[p]=(sum[s[p][0]]+sum[s[p][1]]+v[p])%M;
     25 }
     26 
     27 void mul(int p,ll c)
     28 {
     29     sum[p]=sum[p]*c%M;
     30     v[p]=v[p]*c%M;
     31     lzm[p]=lzm[p]*c%M;
     32     lza[p]=lza[p]*c%M;
     33 }
     34 
     35 void plus(int p,ll c)
     36 {
     37     sum[p]=(sum[p]+sz[p]*c%M)%M;
     38     v[p]=(v[p]+c)%M;
     39     lza[p]=(lza[p]+c)%M;
     40 }
     41 
     42 void pushdown(int p)
     43 {
     44     if(lzm[p]!=1)mul(s[p][0],lzm[p]),mul(s[p][1],lzm[p]),lzm[p]=1;
     45     if(lza[p])plus(s[p][0],lza[p]),plus(s[p][1],lza[p]),lza[p]=0;
     46     if(rev[p])reverse(s[p][0]),reverse(s[p][1]),rev[p]=0;
     47 }
     48 
     49 void rotate(int p)
     50 {
     51     int k=id(p);
     52     int fa=f[p];
     53     if(rt[fa])rt[p]=1,rt[fa]=0;
     54     else s[f[fa]][id(fa)]=p;
     55     s[fa][k]=s[p][!k];
     56     s[p][!k]=fa;
     57     f[p]=f[fa];
     58     f[fa]=p;
     59     f[s[fa][k]]=fa;
     60     pushup(fa);
     61     pushup(p);
     62 }
     63 
     64 void down(int p)
     65 {
     66     if(!rt[p])down(f[p]);
     67     pushdown(p);
     68 }
     69 
     70 void splay(int p)
     71 {
     72     down(p);
     73     while(!rt[p])
     74     {
     75         int fa=f[p];
     76         if(rt[fa])
     77         {
     78             rotate(p);
     79             return;
     80         }
     81         if(id(p)^id(fa))rotate(p);
     82         else rotate(fa);
     83         rotate(p);
     84     }
     85 }
     86 
     87 void access(int p)
     88 {
     89     int son=0;
     90     while(p)
     91     {
     92         splay(p);
     93         rt[s[p][1]]=1,rt[son]=0;
     94         s[p][1]=son;
     95         pushup(p);
     96         son=p,p=f[p];
     97     }
     98 }
     99 
    100 void mtr(int p)
    101 {
    102     access(p);
    103     splay(p);
    104     reverse(p);
    105 }
    106 
    107 void link(int x,int y)
    108 {
    109     mtr(x);
    110     f[x]=y;
    111 }
    112 
    113 void isolate(int x,int y)
    114 {
    115     mtr(x);
    116     access(y);
    117     splay(y);
    118 }
    119 
    120 int main()
    121 {
    122     scanf("%d%d",&n,&q);
    123     for(int i=1;i<=n;i++)lzm[i]=sz[i]=v[i]=rt[i]=1;
    124     for(int i=1;i<n;i++)
    125     {
    126         int x,y;
    127         scanf("%d%d",&x,&y);
    128         link(x,y);
    129     }
    130     while(q--)
    131     {
    132         char op[5];
    133         scanf("%s",op+1);
    134         int pu,pv,nu,nv;
    135         ll c;
    136         if(op[1]=='+')
    137         {
    138             scanf("%d%d%lld",&pu,&pv,&c);
    139             isolate(pu,pv);
    140             plus(pv,c);
    141         }
    142         if(op[1]=='-')
    143         {
    144             scanf("%d%d%d%d",&pu,&pv,&nu,&nv);
    145             isolate(pu,pv);
    146             s[pv][0]=f[pu]=0;
    147             rt[pu]=1;
    148             link(nu,nv);
    149         }
    150         if(op[1]=='*')
    151         {
    152             scanf("%d%d%lld",&pu,&pv,&c);
    153             isolate(pu,pv);
    154             mul(pv,c);
    155         }
    156         if(op[1]=='/')
    157         {
    158             scanf("%d%d",&pu,&pv);
    159             isolate(pu,pv);
    160             printf("%lld
    ",sum[pv]);
    161         }
    162     }
    163     return 0;
    164 }
  • 相关阅读:
    计算直线的交点数
    不容易系列之(4)——考新郎
    神、上帝以及老天爷
    N!
    Number Sequence
    33_ABB机器人智能周期保养与复位操作
    34_WorldZone区域监控功能的使用
    三菱PLC(FX3U)的模拟量应用
    第19集 PLC盒子的使用
    第18集 使用黑盒设计创建宏文件
  • 原文地址:https://www.cnblogs.com/eternhope/p/9650983.html
Copyright © 2011-2022 走看看