【BZOJ3091】城市旅行

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

Solution

前三个操作link-cut tree的本职工作。最后一个解法优秀。。。我们发现每一个点对期望的贡献可以由它的位置和路径的长度在O(1)的时间内转移。然后再简单调用一些数学公式简化式子,维护即可。题解就去%PoPoQQQ大爷的blog:%%%PoPoQQQ%%%

CODE

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MaxN=50005;
inline int read(){char c;int rec=0,f=1;while((c=getchar())<'0'||c>'9')if(c=='-')f=-1;while(c>='0'&&c<='9')rec=rec*10+c-'0',c=getchar();return rec*f;
}
int n,m;
struct Branch {int next,to;}branch[100005];
int h[50005],cnt=0;
inline void add(int x,int y){branch[++cnt].to=y;branch[cnt].next=h[x];h[x]=cnt;return ;}
struct Lct_Tree{int F,s[2],val;long long lexp,rexp,sum,size;long long exp,rev,add;inline void NewNode(int x){F=s[0]=s[1]=0;size=1;val=lexp=rexp=sum=exp=x;rev=add=0;return ;}
}tree[50005];
inline void Dfs(int v,int pre){tree[v].F=pre;for(int i=h[v];i;i=branch[i].next){int j=branch[i].to;if(j==pre)continue;Dfs(j,v);}return ;
}
inline bool Isroot(int v){return tree[tree[v].F].s[0]!=v&&tree[tree[v].F].s[1]!=v;}
inline void Pushup(int v){tree[v].size=tree[tree[v].s[0]].size+1+tree[tree[v].s[1]].size;tree[v].sum=tree[tree[v].s[0]].sum+tree[v].val+tree[tree[v].s[1]].sum;tree[v].lexp=tree[tree[v].s[0]].lexp+tree[v].val*(tree[tree[v].s[0]].size+1)+tree[tree[v].s[1]].lexp+tree[tree[v].s[1]].sum*(tree[tree[v].s[0]].size+1);tree[v].rexp=tree[tree[v].s[1]].rexp+tree[v].val*(tree[tree[v].s[1]].size+1)+tree[tree[v].s[0]].rexp+tree[tree[v].s[0]].sum*(tree[tree[v].s[1]].size+1);tree[v].exp=tree[tree[v].s[0]].exp+tree[tree[v].s[1]].exp+(tree[tree[v].s[0]].size+1)*tree[tree[v].s[1]].rexp+(tree[tree[v].s[1]].size+1)*tree[tree[v].s[0]].lexp+tree[v].val*(tree[tree[v].s[0]].size+1)*(tree[tree[v].s[1]].size+1);return ;
}
inline void Rev(int v){if(v==0)return ;tree[v].rev^=1;swap(tree[v].s[0],tree[v].s[1]);swap(tree[v].lexp,tree[v].rexp);return ;
}
inline void Add(int v,int x){if(v==0)return ;tree[v].add+=x;tree[v].val+=x;tree[v].sum+=x*tree[v].size;tree[v].lexp+=x*tree[v].size*(tree[v].size+1)/2;tree[v].rexp+=x*tree[v].size*(tree[v].size+1)/2;tree[v].exp+=x*tree[v].size*(tree[v].size+1)*(tree[v].size+2)/6;return ;
}
inline void Pushdown(int v){if(tree[v].rev){Rev(tree[v].s[0]);Rev(tree[v].s[1]);tree[v].rev=0;}if(tree[v].add){Add(tree[v].s[0],tree[v].add);Add(tree[v].s[1],tree[v].add);tree[v].add=0;}return ;
}
inline void Lazy(int v){if(!Isroot(v))Lazy(tree[v].F);Pushdown(v);return ;}
inline void Rotate(int v){int p=tree[v].F,g=tree[p].F;int t1=v==tree[p].s[1],t2=p==tree[g].s[1],S=tree[v].s[1^t1];if(!Isroot(p))tree[g].s[t2]=v;tree[v].F=g;tree[p].s[t1]=S;tree[S].F=p;tree[v].s[1^t1]=p;tree[p].F=v;Pushup(p);return;
}
inline void Splay(int v){Lazy(v);while(!Isroot(v)){int p=tree[v].F,g=tree[p].F;if(!Isroot(p))(v==tree[p].s[1])^(p==tree[g].s[1])?Rotate(v):Rotate(p);Rotate(v);}Pushup(v);return;
}
inline void Access(int v){for(int temp=0;v;temp=v,v=tree[v].F){Splay(v);tree[v].s[1]=temp;Pushup(v);}return ;
}
inline void Make_Root(int v){Access(v);Splay(v);Rev(v);return ;}
inline int Find_Root(int v){while(tree[v].F)v=tree[v].F;return v;}
inline void Link(int v1,int v2){Make_Root(v1);tree[v1].F=v2;return ;}
inline void Cut(int v1,int v2){Make_Root(v1);Access(v2);Splay(v2);if(tree[v2].s[0]==v1&&tree[v1].s[1]==0){tree[v2].s[0]=tree[v1].F=0;Pushup(v2);}return ;
}
inline void Insert(int v1,int v2,int x){Make_Root(v1);Access(v2);Splay(v2);Add(v2,x);return ;}
inline long long Gcd(long long a,long long b){if(b==0)return a;return Gcd(b,a%b);}
inline void Print(int v){long long a=tree[v].exp,b=tree[v].size*(tree[v].size+1)>>1;long long d=Gcd(a,b);cout<<(a/d)<<'/'<<(b/d)<<'\n';return ;
}
inline void Ask(int v1,int v2){Make_Root(v1);Access(v2);Splay(v2);Print(v2);return ;}
int main(){n=read();m=read();for(int i=1;i<=n;i++)tree[i].NewNode(read());for(int i=1;i<n;i++){int x=read(),y=read();add(x,y);add(y,x);}Dfs(1,0);for(int i=1;i<=m;i++){int f=read(),x=read(),y=read();switch (f){case 1:{if(Find_Root(x)==Find_Root(y)&&x!=y)Cut(x,y);break;}case 2:{if(Find_Root(x)!=Find_Root(y))Link(x,y);break;}case 3:{int z=read();if(Find_Root(x)==Find_Root(y))Insert(x,y,z);break;}case 4:{if(Find_Root(x)==Find_Root(y))Ask(x,y);else cout<<-1<<'\n';break;}}}return 0;
}

更正式的题解哪天完全搞懂了,有时间的时候补上。就是Pushup里的一个乘号被写成了加号,眼瞎的蒟蒻选手一晚上才找出来。。。

【BZOJ3091】城市旅行相关推荐

  1. BZOJ3091: 城市旅行

    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 ...

  2. bzoj 3091 城市旅行

    3091: 城市旅行 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1697  Solved: 565 [Submit][Status][Discu ...

  3. BZOJ 3091 城市旅行 (LCT)

    3091: 城市旅行 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 2251  Solved: 761 [Submit][Status][Discu ...

  4. [BZOJ3091][LCT]城市旅行

    BZOJ3091 LCT简单题 计算期望比较简单吧,都是平衡树基操 但是BZOJ算总时间过了,单点有的我要跑1.5s Code: #include<bits/stdc++.h> #defi ...

  5. 基于机器学习预测Airbnb的城市旅行成本

    本文为翻译发表,转载需要注明来自公众号EAWorld. 作者:Sean Kim 译者:白小白 原题:一文了解Airbnb的旅行成本 原文:http://t.cn/E2FvawU 全文3538字,阅读约 ...

  6. 【LCT】城市旅行(luogu 4842/金牌导航 LCT-3)

    正题 luogu 4842 金牌导航 LCT-3 题目大意 给你一棵树,让你进行一些操作: 1.删除一条边 2.连接一条边 3.给一条路径上的点加上x 4.给出一条路径,在该路径选取两个点,求这两个点 ...

  7. BZOJ 3091: 城市旅行 LCT

    这个合并还是相当复杂的. code: #include <cstdio> #include <cstring> #include <string> #include ...

  8. BZOJ 3091 城市旅行 Link-Cut-Tree

    警告:此题不可以使用cout进行输出,只能用printf,否则RE!亲测!! 题目大意:给定一棵树,每个点有一个点权,提供四种操作: 1.删除两点之间的连边 不存在边则无视 2.在两点之前连接一条边 ...

  9. 人工智能和物联网:智慧城市的交通管理

    来源:帮尼资讯 当今的智慧城市由不断重塑城市地区的先进技术提供发展驱动力.人工智能和物联网对于世界的运作越来越不可或缺.基于云的服务.物联网.分析平台和许多AI工具正在改变城市居民与环境互动和在环境中 ...

最新文章

  1. 分布式 java 应用:基础与实践_西研技术大讲堂第二期FRCS应用情况介绍及分布式技术平台能力应用实践...
  2. debug调到循环最后_Java入门(7)——循环和debug 调试
  3. 使用Harbor构建docker私有仓库
  4. 7_CentOS下安装和卸载AdobeReader
  5. 自己搭建一个k8s环境
  6. python程序设计方法_Python程序设计现代方法
  7. 【python】IP地址处理模块IPy
  8. Linux挂载iso文件步骤
  9. 测试面试题,自动化测试与性能测试篇(附答案)
  10. golang微服务网关
  11. html如何将图片做成背景图片,css如何设置网页背景图片?
  12. Ubuntu(debian) 程序 dep 打包
  13. android_97_TouchSlop
  14. 准备嵌入式Linux开发环境
  15. 为什么说运维的未来必然是 AIOps?
  16. Cloudreve离线下载Aria2安装教程
  17. 师徒结对活动记录表计算机,师徒结对活动记录表一.doc
  18. 驼峰命名法等命名规范
  19. 工作第十五周:上线前的惊悚
  20. Kendo UI 绑定行点击事件

热门文章

  1. php打印机,PHP云打印类完整示例
  2. 黑科技机器人,竟然能干木工装修的活,将颠覆建筑业!
  3. vue实现视频截图(webRTC、屏幕快照)笔记
  4. OMPL138及U-Boot的启动过程分析(三)
  5. 4921-字符串连接 ZCMU
  6. macOS Monterey 12.6 (21G115) Boot ISO 原版可引导镜像
  7. java并发编程--get超时处理以及cancle方法的使用
  8. 麓言信息时尚史上影响力的十位女性设计师!
  9. 数据结构单向链表线性结构_线性数据结构链表为何以及如何解释
  10. 新规之下产业园区如何合理收费水电费用?