zoukankan      html  css  js  c++  java
  • BZOJ3091: 城市旅行(LCT,数学期望)

    Description

    Input

    Output

    Sample Input

    4 5
    1 3 2 5
    1 2
    1 3
    2 4
    4 2 4
    1 2 4
    2 3 4
    3 1 4 1
    4 1 4

    Sample Output

    16/3
    6/1

    解题思路:

    大爷比我讲得好到不知道哪里去了PoPoQQQ的博客

    就是考虑一个点会被经过多少次*多少贡献,感觉这个好套路,线性求解不是问题,不会动态维护QAQ。

    考虑一个点代表的子树信息内部处理完毕,处理左子树对右子树或右子树对左子树的影响,像分治的想法QAQ。

    最后累计答案就累计左子树答案+右子树答案+自己答案+左对右答案+右对左答案就好了。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lll tr[spc].ch[0]
      5 #define rrr tr[spc].ch[1]
      6 #define ls ch[0]
      7 #define rs ch[1]
      8 typedef long long lnt;
      9 const int N=100010;
     10 struct trnt{
     11     int ch[2];
     12     int fa;
     13     int lzt;
     14     int wgt;
     15     lnt add;
     16     lnt val;
     17     lnt ans;
     18     lnt sum;
     19     lnt lsum;
     20     lnt rsum;
     21     bool anc;
     22 }tr[N];
     23 int n,m;
     24 bool whc(int spc)
     25 {
     26     return tr[tr[spc].fa].rs==spc;
     27 }
     28 void pushup(int spc)
     29 {
     30     if(!spc)
     31         return ;
     32     tr[spc].wgt=tr[lll].wgt+tr[rrr].wgt+1;
     33     tr[spc].sum=tr[lll].sum+tr[rrr].sum+tr[spc].val;
     34     tr[spc].lsum=tr[lll].lsum+tr[rrr].lsum+tr[spc].val*(tr[lll].wgt+1)+tr[rrr].sum*(tr[lll].wgt+1);
     35     tr[spc].rsum=tr[lll].rsum+tr[rrr].rsum+tr[spc].val*(tr[rrr].wgt+1)+tr[lll].sum*(tr[rrr].wgt+1);
     36     tr[spc].ans=tr[lll].ans+tr[rrr].ans+tr[lll].lsum*(tr[rrr].wgt+1)+tr[rrr].rsum*(tr[lll].wgt+1)+tr[spc].val*(tr[lll].wgt+1)*(tr[rrr].wgt+1);
     37     return ;
     38 }
     39 void Add(int spc,lnt v)
     40 {
     41     if(!spc)
     42         return ;
     43     tr[spc].add+=v;
     44     tr[spc].val+=v;
     45     tr[spc].sum+=v*tr[spc].wgt;
     46     tr[spc].lsum+=v*(tr[spc].wgt)*(tr[spc].wgt+1)/2;
     47     tr[spc].rsum+=v*(tr[spc].wgt)*(tr[spc].wgt+1)/2;
     48     tr[spc].ans+=v*(tr[spc].wgt+2)*(tr[spc].wgt+1)*tr[spc].wgt/6;
     49     return ;
     50 }
     51 void trr(int spc)
     52 {
     53     if(!spc)
     54         return ;
     55     tr[spc].lzt^=1;
     56     std::swap(lll,rrr);
     57     std::swap(tr[spc].lsum,tr[spc].rsum);
     58     return ;
     59 }
     60 void pushdown(int spc)
     61 {
     62     if(tr[spc].lzt)
     63     {
     64         trr(lll);
     65         trr(rrr);
     66         tr[spc].lzt=0;
     67     }
     68     if(tr[spc].add)
     69     {
     70         Add(lll,tr[spc].add);
     71         Add(rrr,tr[spc].add);
     72         tr[spc].add=0;
     73     }
     74     return ;
     75 }
     76 void recal(int spc)
     77 {
     78     if(!tr[spc].anc)
     79         recal(tr[spc].fa);
     80     pushdown(spc);
     81     return ;
     82 }
     83 void rotate(int spc)
     84 {
     85     int f=tr[spc].fa;
     86     bool k=whc(spc);
     87     tr[f].ch[k]=tr[spc].ch[!k];
     88     tr[spc].ch[!k]=f;
     89     if(tr[f].anc)
     90     {
     91         tr[spc].anc=true;
     92         tr[f].anc=false;
     93     }else
     94         tr[tr[f].fa].ch[whc(f)]=spc;
     95     tr[spc].fa=tr[f].fa;
     96     tr[f].fa=spc;
     97     tr[tr[f].ch[k]].fa=f;
     98     pushup(f);
     99     pushup(spc);
    100     return ;
    101 }
    102 void splay(int spc)
    103 {
    104     recal(spc);
    105     while(!tr[spc].anc)
    106     {
    107         int f=tr[spc].fa;
    108         if(tr[f].anc)
    109         {
    110             rotate(spc);
    111             return ;
    112         }
    113         if(whc(spc)^whc(f))
    114             rotate(spc);
    115         else
    116             rotate(f);
    117         rotate(spc);
    118     }
    119     return ;
    120 }
    121 void access(int spc)
    122 {    
    123     int lst=0;
    124     while(spc)
    125     {
    126         splay(spc);
    127         tr[rrr].anc=true;
    128         tr[lst].anc=false;
    129         rrr=lst;
    130         pushup(spc);
    131         lst=spc;
    132         spc=tr[spc].fa;
    133     }
    134     return ;
    135 }
    136 void Mtr(int spc)
    137 {
    138     access(spc);
    139     splay(spc);
    140     trr(spc);
    141     return ;
    142 }
    143 void split(int x,int y)
    144 {
    145     Mtr(x);
    146     access(y);
    147     splay(y);
    148     return ;
    149 }
    150 bool together(int x,int y)
    151 {
    152     split(x,y);
    153     while(tr[y].ls)
    154         y=tr[y].ls;
    155     return x==y;
    156 }
    157 void link(int x,int y)
    158 {
    159     split(x,y);
    160     tr[x].fa=y;
    161     return ;
    162 }
    163 void cut(int x,int y)
    164 {
    165     split(x,y);
    166     tr[y].ls=0;
    167     tr[x].fa=0;
    168     tr[x].anc=true;
    169     pushup(y);
    170     return ;
    171 }
    172 lnt gcd(lnt a,lnt b)
    173 {
    174     if(!b)
    175         return a;
    176     return gcd(b,a%b);
    177 }
    178 int main()
    179 {
    180     scanf("%d%d",&n,&m);
    181     for(int i=1;i<=n;i++)
    182     {
    183         scanf("%lld",&tr[i].val);
    184         tr[i].anc=true;
    185         pushup(i);
    186     }
    187     for(int i=1;i<n;i++)
    188     {
    189         int a,b;
    190         scanf("%d%d",&a,&b);
    191         link(a,b);
    192     }
    193     while(m--)
    194     {
    195         int cmd;
    196         scanf("%d",&cmd);
    197         if(cmd==1)
    198         {
    199             int u,v;
    200             scanf("%d%d",&u,&v);
    201             if(together(u,v))
    202                 cut(u,v);
    203         }else if(cmd==2)
    204         {
    205             int u,v;
    206             scanf("%d%d",&u,&v);
    207             if(!together(u,v))
    208                 link(u,v);
    209         }else if(cmd==3)
    210         {
    211             int u,v,d;
    212             scanf("%d%d%d",&u,&v,&d);
    213             if(together(u,v))
    214                 Add(v,d);
    215         }else{
    216             int u,v;
    217             scanf("%d%d",&u,&v);
    218             if(!together(u,v))
    219                 printf("%d
    ",-1);
    220             else{
    221                 lnt top=tr[v].ans;
    222                 lnt bot=(lnt)(tr[v].wgt)*(lnt)(tr[v].wgt+1)/2;
    223                 lnt c=gcd(top,bot);
    224                 top/=c,bot/=c;
    225                 printf("%lld/%lld
    ",top,bot);
    226             }
    227         }
    228     }
    229     return 0;
    230 }

     

  • 相关阅读:
    [Angular 2] Refactoring mutations to enforce immutable data in Angular 2
    人物-释-鸠摩罗什:鸠摩罗什
    汉语-词语:说法
    汉语-词语:做法
    汉语-词语:办法
    汉语-词语:想法
    汉语-词语:看法
    汉语-词语:观念
    汉语-词语:逻辑
    汉语-词语:实质
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10158863.html
Copyright © 2011-2022 走看看