zoukankan      html  css  js  c++  java
  • bzoj3091: 城市旅行

    地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3091

    题目:

    3091: 城市旅行

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1839  Solved: 599
    [Submit][Status][Discuss]

    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

    HINT

    对于所有数据满足 1<=N<=50,000 1<=M<=50,000 1<=Ai<=10^6 1<=D<=100 1<=U,V<=N

     
    吐槽:
      强行把裸lct变难。
    思路:
      看popoqqq的博客吧。。。
      注意reverse操作时要swap(lsum,rsum).
      1 /**************************************************************
      2     Problem: 3091
      3     User: weeping
      4     Language: C++
      5     Result: Accepted
      6     Time:3332 ms
      7     Memory:5796 kb
      8 ****************************************************************/
      9  
     10 #include <bits/stdc++.h>
     11  
     12 typedef long long LL;
     13  
     14 using namespace std;
     15  
     16 struct Link_Cut_Tree
     17 {
     18     static const int MAXN = 60000 + 7;
     19  
     20     int ch[MAXN][2], fa[MAXN], rev[MAXN];
     21     LL v[MAXN], lz[MAXN], sz[MAXN], sum[MAXN], lsum[MAXN], rsum[MAXN], ep[MAXN];
     22     int sk[MAXN];
     23  
     24     bool isroot(int x)
     25     {
     26         return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
     27     }
     28  
     29     void reverse(int x)
     30     {
     31         rev[x] ^= 1, swap(ch[x][0],ch[x][1]), swap(lsum[x],rsum[x]);
     32     }
     33     void lazy(int x,LL d)
     34     {
     35         v[x] += d, lz[x] += d, sum[x] += sz[x] * d;
     36         lsum[x] += sz[x] * (sz[x] + 1) / 2 * d;
     37         rsum[x] += sz[x] * (sz[x] + 1) / 2 * d;
     38         ep[x] += sz[x] * (sz[x] + 1) * (sz[x] + 2) / 6 * d;
     39     }
     40     void update(int x)
     41     {
     42         int lc = ch[x][0], rc = ch[x][1];
     43         sz[x] = sz[lc] +  sz[rc] + 1;
     44         sum[x] = sum[lc] + sum[rc] + v[x];
     45         lsum[x] = lsum[lc] + lsum[rc] + (sz[lc] + 1) * (sum[rc] + v[x]);
     46         rsum[x] = rsum[lc] + rsum[rc] + (sz[rc] + 1) * (sum[lc] + v[x]);
     47         ep[x] = ep[lc] + ep[rc] + lsum[lc]*(sz[rc]+1) + rsum[rc]*(sz[lc]+1) + v[x]*(sz[lc]+1)*(sz[rc]+1);
     48     }
     49  
     50     void push_down(int x)
     51     {
     52         if(rev[x])
     53         {
     54             if(ch[x][0]) reverse(ch[x][0]);
     55             if(ch[x][1]) reverse(ch[x][1]);
     56             rev[x]=0;
     57         }
     58         if(lz[x])
     59         {
     60             if(ch[x][0]) lazy(ch[x][0],lz[x]);
     61             if(ch[x][1]) lazy(ch[x][1],lz[x]);
     62             lz[x]=0;
     63         }
     64     }
     65  
     66     void rotate(int x)
     67     {
     68         int f = fa[x], gf = fa[f];
     69         int t1 = ( x != ch[f][0]), t2 = ( f != ch[gf][0]), tmp = ch[x][1^t1];
     70         if(!isroot(f)) ch[gf][0^t2] = x;
     71         fa[tmp] = f, fa[x] = gf, ch[x][1^t1] = f, fa[f] = x, ch[f][0^t1] = tmp;
     72         update(f);
     73     }
     74  
     75     void splay(int x)
     76     {
     77         int top = 0;
     78         sk[++top] = x;
     79         for(int i = x; !isroot(i); i = fa[i])   sk[++top] = fa[i];
     80         while(top)  push_down(sk[top--]);
     81         for(int f = fa[x], gf = fa[f]; !isroot(x); rotate(x), f = fa[x],gf = fa[f])
     82         if(!isroot(f))
     83             rotate((x==ch[f][0]) ^ (f==ch[gf][0]) ? x : f);
     84         update(x);
     85     }
     86  
     87     void access(int x)
     88     {
     89         for(int p = 0; x; p = x, x = fa[x])
     90             splay(x), ch[x][1] = p, update(x);
     91     }
     92  
     93     void makeroot(int x)
     94     {
     95         access(x), splay(x), reverse(x);
     96     }
     97  
     98     int findroot(int x)
     99     {
    100         access(x), splay(x);
    101         while(ch[x][0]) x = ch[x][0];
    102         return x;
    103     }
    104     void link(int x,int y)
    105     {
    106         makeroot(x), fa[x] = y;
    107     }
    108  
    109     void cut(int x,int y)
    110     {
    111         makeroot(x), access(y), splay(y);
    112         if(ch[y][0] == x)   ch[y][0] = fa[x] = 0;
    113         update(y);
    114     }
    115  
    116     void debug(void)
    117     {
    118         for(int i=1;i<=100;i++)
    119             printf("%d %d %d %d %d %d %d
    ",i,fa[i],ch[i][0],ch[i][1],rev[i],sz[i]);
    120     }
    121  
    122     void work(int n)
    123     {
    124         int op,x,y,z;
    125         scanf("%d%d%d",&op,&x,&y);
    126         if(op==1)
    127         {
    128             if(findroot(x)==findroot(y))
    129                 cut(x,y);
    130         }
    131         else if(op==2)
    132         {
    133             if(findroot(x)!=findroot(y))
    134                 link(x,y);
    135         }
    136         else if(op==3)
    137         {
    138             scanf("%d",&z);
    139             if(findroot(x) == findroot(y))
    140                 makeroot(x),access(y),splay(y),lazy(y,z);
    141         }
    142         else
    143         {
    144             if(findroot(x)!=findroot(y))
    145             {
    146                 printf("-1
    ");return ;
    147             }
    148             makeroot(x),access(y),splay(y);
    149             LL ta = ep[y],tb = sz[y] * (sz[y] + 1) / 2;
    150             LL tc = __gcd(ta,tb);
    151             printf("%lld/%lld
    ",ta/tc,tb/tc);
    152         }
    153     }
    154 }lct;
    155  
    156 int n,m;
    157  
    158 int main(void)
    159 {
    160     scanf("%d%d",&n,&m);
    161     for(int i=1,x;i<=n;i++)
    162         scanf("%d",&x),lct.sz[i]=1,lct.v[i]=x;
    163     for(int i=1,x,y;i<n;i++)
    164         scanf("%d%d",&x,&y),lct.link(x,y);
    165     while(m--)  lct.work(n);
    166     return 0;
    167 }
  • 相关阅读:
    编译安装LEMP
    eAccelerator配置和使用指南
    /dev/null的用途
    分库分表
    JVM
    SOFA 数据透析
    HTTPS
    SOFA 通信
    分布式锁
    mysql 锁
  • 原文地址:https://www.cnblogs.com/weeping/p/7617219.html
Copyright © 2011-2022 走看看