欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - BZOJ3091


题意概括

  鉴于本人语文不好,此题的描述原题很清晰,废话不多,请看原题。

  可怕,原题是图片,不可以复制题目+删掉废话了……


题解

  http://blog.csdn.net/popoqqq/article/details/40823659

  这位大佬写的很好。

  我的代码在找错的时候一边找,一边该,然后发现和他改的好像……


代码

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
typedef long long LL;
const int N=50005;
struct Gragh{
int cnt,y[N*2],nxt[N*2],fst[N];
void clear(){
cnt=0;
memset(fst,0,sizeof fst);
}
void add(int a,int b){
y[++cnt]=b,nxt[cnt]=fst[a],fst[a]=cnt;
}
}g;
int n,m;
int fa[N],son[N][2],rev[N];
LL size[N],val[N],add[N],sum[N],Lsum[N],Rsum[N],Exp[N];
bool isroot(int x){
return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;
}
void pushup(int x){
int ls=son[x][0],rs=son[x][1],lsz=size[ls],rsz=size[rs];
size[x]=lsz+rsz+1;
sum[x]=sum[ls]+sum[rs]+val[x];
Lsum[x]=Lsum[ls]+(lsz+1)*val[x]+Lsum[rs]+sum[rs]*(lsz+1);
Rsum[x]=Rsum[rs]+(rsz+1)*val[x]+Rsum[ls]+sum[ls]*(rsz+1);
Exp[x]=Exp[ls]+Exp[rs]+Lsum[ls]*(rsz+1)+Rsum[rs]*(lsz+1)+val[x]*(lsz+1)*(rsz+1);
}
void pushson(int x,LL v){
if (!x)
return;
val[x]+=v,sum[x]+=v*size[x],add[x]+=v;
Lsum[x]+=v*size[x]*(size[x]+1)/2;
Rsum[x]+=v*size[x]*(size[x]+1)/2;
Exp[x]+=v*size[x]*(size[x]+1)*(size[x]+2)/6;
}
void pushrev(int x){
rev[x]^=1;
swap(son[x][0],son[x][1]);
swap(Lsum[x],Rsum[x]);
}
void pushdown(int x){
int &ls=son[x][0],&rs=son[x][1];
if (rev[x]){
rev[x]=0;
pushrev(ls);
pushrev(rs);
}
if (add[x]){
LL &a=add[x];
pushson(ls,a);
pushson(rs,a);
a=0;
}
}
void pushadd(int x){
if (!isroot(x))
pushadd(fa[x]);
pushdown(x);
}
int wson(int x){
return son[fa[x]][1]==x;
}
void rotate(int x){
if (isroot(x))
return;
int y=fa[x],z=fa[y],L=wson(x),R=L^1;
if (!isroot(y))
son[z][wson(y)]=x;
fa[x]=z,fa[y]=x,fa[son[x][R]]=y;
son[y][L]=son[x][R],son[x][R]=y;
pushup(y),pushup(x);
}
void splay(int x){
pushadd(x);
for (int y=fa[x];!isroot(x);rotate(x),y=fa[x])
if (!isroot(y))
rotate(wson(x)==wson(y)?y:x);
}
void access(int x){
int t=0;
while (x){
splay(x);
son[x][1]=t;
pushup(x);
t=x;
x=fa[x];
}
}
void rever(int x){
access(x);
splay(x);
pushrev(x);
}
void link(int x,int y){
rever(x);
fa[x]=y;
}
void cut(int x,int y){
rever(x);
access(y);
splay(y);
fa[x]=son[y][0]=0;
}
int find(int x){
access(x);
splay(x);
while (1){
pushdown(x);
if (son[x][0])
x=son[x][0];
else
break;
}
return x;
}
void dfs(int x,int pre){
fa[x]=pre;
for (int i=g.fst[x];i;i=g.nxt[i])
if (g.y[i]!=pre)
dfs(g.y[i],x);
}
LL gcd(LL a,LL b){
return b==0?a:gcd(b,a%b);
}
void solve(int x,int y){
if (find(x)!=find(y)){
puts("-1");
return;
}
rever(x);
access(y);
splay(y);
LL a=Exp[y];
LL b=size[y]*(size[y]+1)/2;
LL Gcd=gcd(a,b);
a/=Gcd,b/=Gcd;
printf("%lld/%lld\n",a,b);
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++){
scanf("%lld",&val[i]);
fa[i]=son[i][0]=son[i][1]=rev[i]=0;
size[i]=1,Exp[i]=Lsum[i]=Rsum[i]=sum[i]=val[i],add[i]=0;
}
g.clear();
for (int i=1,a,b;i<n;i++){
scanf("%d%d",&a,&b);
g.add(a,b),g.add(b,a);
}
dfs(1,0);
for (int i=1;i<=m;i++){
int op,x,y;
LL v;
scanf("%d%d%d",&op,&x,&y);
if (op==1){
if (find(x)==find(y))
cut(x,y);
}
else if (op==2){
if (find(x)!=find(y))
link(x,y);
}
else if (op==3){
scanf("%lld",&v);
if (find(x)!=find(y))
continue;
rever(x);
access(y);
splay(y);
pushson(y,v);
}
else
solve(x,y);
}
return 0;
}

  

BZOJ3091 城市旅行 LCT的更多相关文章

  1. BZOJ3091城市旅行——LCT区间信息合并

    题目描述 输入 输出 样例输入 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 样例输出 16/3 6/1 提示 对于所有数据满足 1& ...

  2. bzoj3091 城市旅行 LCT + 区间合并

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3091 题解 调了整个晚自习才调出来的问题. 乍一看是个 LCT 板子题. 再看一眼还是个 LC ...

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

  4. 【BZOJ3091】城市旅行 LCT

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

  5. 【LCT】BZOJ3091 城市旅行

    3091: 城市旅行 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1927  Solved: 631[Submit][Status][Discuss ...

  6. BZOJ 3091: 城市旅行 [LCT splay 期望]

    3091: 城市旅行 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1454  Solved: 483[Submit][Status][Discuss ...

  7. 【bzoj3091】城市旅行 LCT区间合并

    题目描述 输入 输出 样例输入 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 样例输出 16/3 6/1 题解 LCT区间合并 前三个 ...

  8. BZOJ 3091: 城市旅行 lct 期望 splay

    https://www.lydsy.com/JudgeOnline/problem.php?id=3091 https://blog.csdn.net/popoqqq/article/details/ ...

  9. bzoj 3091: 城市旅行 LCT

    题目: http://www.lydsy.com/JudgeOnline/problem.php?id=3091 题解: 首先前三个操作就是裸的LCT模板 只考虑第四个操作. 要求我们计算期望,所以我 ...

随机推荐

  1. 工控安全入门之Modbus(转载)

    工控安全这个领域比较封闭,公开的资料很少.我在读<Hacking Exposed Industrial Control Systems>,一本16年的书,选了的部分章节进行翻译,以其抛砖引 ...

  2. 20155205 2016-2017-2 《Java程序设计》第5周学习总结

    20155205 2016-2017-2 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 如果没有try的话,出现异常会导致程序崩溃,而try则可以保证程序的正常运行下去.( ...

  3. comfirm和prompt的区别

    comfirm和prompt的区别. <html> <title>测试页面</title> <head> </head> <body& ...

  4. day1 查看当前目录命令:pwd

    用到查看当前目录的完整路径使用:pwd 物理路径和连接路径什么鬼?没明白暂时借鉴别人的记录下 显示当前目录的物理路径 pwd –P 1: [root@DB-Server init.d]# cd /et ...

  5. 交换机console口连接

    http://www.webkaka.com/info/archives/knowledge/2010/08/30452/

  6. mysql 原理 ~ 二阶段提交协议通说

    一 简介: 今天是第二篇,讲解的是mysql的事务日志 二 具体 1 WAL技术(先写日志,再写磁盘) 2 binlog redolog 二阶段提交协议     目的 保持 redo log和binl ...

  7. 网易云课堂--妙味 《js基础课程》

    ==小例子1   ==JS中允许将"." 替换成 “[ ]” document.getElementById('btn1') 写成 document['etElementById' ...

  8. 【转】linux的特殊符号与正则表达式

    [转]linux的特殊符号与正则表达式 第1章 linux的特殊符号 1.1 通配符 * {} 1.1.1 含义 方便查找文件 通配符是用来找文件名字的. 1.1.2  * 通过find 命令找以 . ...

  9. STM32F103X datasheet学习笔记---GPIOs and AFIOs

    1.前言 每个GPIO端口有如下几个寄存器进行操作: 两个32位配置寄存器:GPIOx_CRL, GPIOx_CRH 两个32位数据寄存器:GPIOx_IDR, GPIOx_ODR 一个32位set/ ...

  10. XAF 与 CIIP

    XAF 与 CIIP:网站:http://www.uims.top, XAF技术博客:http://www.cnblogs.com/foreachlife/ tylike 升级到  DevExpres ...