这个合并还是相当复杂的.

code:

#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <algorithm>
#define N 50005
#define ll long long
#define siz size
#define ts tag
#define lson s[x].ch[0]
#define rson s[x].ch[1]
#define get(x) (s[s[x].f].ch[1]==x)
#define Isr(x) (!(s[s[x].f].ch[0]==x||s[s[x].f].ch[1]==x))
using namespace std;   ll sqr(ll x) { return x*x;  }
ll calc1(ll x) { return x*(x+1ll)/2; }
ll calc2(ll x) { return x*(x+1ll)*(2ll*x+1ll)/6; }
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;  }namespace IO {      void setIO(string s) {string in=s+".in"; string out=s+".out"; freopen(in.c_str(),"r",stdin); freopen(out.c_str(),"w",stdout); }     };          int sta[N];
map<int,int>con[N];        struct node { int ch[2],rev,f; ll s0[2],s1[2],s2[2],tag,v,size;
}s[N];          void Pushup(int x)
{           s[x].size=s[lson].size+s[rson].size+1;  s[x].s0[0]=s[lson].s0[0]+s[rson].s0[0]+s[x].v;     s[x].s1[0]=s[lson].s1[0]+s[rson].s1[0]+(s[rson].s0[0]+s[x].v)*(s[lson].size+1);        s[x].s2[0]=s[s[x].ch[0]].s2[0]+s[s[x].ch[1]].s2[0]+(s[s[x].ch[1]].s0[0]+s[x].v)*(s[s[x].ch[0]].size+1)*(s[s[x].ch[0]].size+1)+2ll*s[s[x].ch[1]].s1[0]*(s[s[x].ch[0]].size+1);      s[x].s0[1]=s[lson].s0[1]+s[rson].s0[1]+s[x].v;   s[x].s1[1]=s[rson].s1[1]+s[lson].s1[1]+(s[lson].s0[1]+s[x].v)*(s[rson].size+1);        s[x].s2[1]=s[s[x].ch[1]].s2[1]+s[s[x].ch[0]].s2[1]+(s[s[x].ch[0]].s0[1]+s[x].v)*(s[s[x].ch[1]].size+1)*(s[s[x].ch[1]].size+1)+2ll*s[s[x].ch[0]].s1[1]*(s[s[x].ch[1]].size+1);
} void Up_tag(int x,ll v)
{      s[x].v+=v;      s[x].tag+=v;  s[x].s0[0]+=s[x].size*v;        s[x].s0[1]+=s[x].size*v;          s[x].s1[0]+=calc1(s[x].size)*v; s[x].s1[1]+=calc1(s[x].size)*v;        s[x].s2[0]+=calc2(s[x].size)*v;   s[x].s2[1]+=calc2(s[x].size)*v;
}  void Up_rev(int x)
{  s[x].rev^=1; swap(lson,rson); swap(s[x].s0[0],s[x].s0[1]); swap(s[x].s1[0],s[x].s1[1]),swap(s[x].s2[0],s[x].s2[1]);
}  void Pushdown(int x)
{ if(s[x].tag) {if(lson) Up_tag(lson,s[x].tag); if(rson) Up_tag(rson,s[x].tag); s[x].tag=0; }if(s[x].rev) {if(lson) Up_rev(lson); if(rson) Up_rev(rson);    s[x].rev=0;        }
}  void rotate(int x)
{    int old=s[x].f,fold=s[old].f,which=get(x);   if(!Isr(old)) s[fold].ch[s[fold].ch[1]==old]=x;     s[old].ch[which]=s[x].ch[which^1]; if(s[old].ch[which]) s[s[old].ch[which]].f=old; s[x].ch[which^1]=old,s[old].f=x,s[x].f=fold; Pushup(old),Pushup(x);
}void Splay(int x)
{     int v=0,u=x,fa; for(sta[++v]=u;!Isr(u);u=s[u].f)  sta[++v]=s[u].f;  for(;v;--v)  Pushdown(sta[v]);   for(u=s[u].f;(fa=s[x].f)!=u;rotate(x))   {   if(s[fa].f!=u) rotate(get(fa)==get(x)?fa:x);}
}           void Access(int x)
{for(int y=0;x;y=x,x=s[x].f)  {Splay(x);     rson=y; Pushup(x);  }
}void Make_Root(int x)
{Access(x); Splay(x); Up_rev(x);
}void Link_Edge(int x,int y)
{    Access(x),Splay(x); Make_Root(y);   s[y].f=x;
}    void Cut_Edge(int x,int y)
{     Make_Root(x),Access(y),Splay(y);    if(!s[x].ch[1]&&s[y].ch[0]==x)   s[y].ch[0]=s[x].f=0;            Pushup(y);
}void Split(int x,int y)
{Make_Root(x),Access(y),Splay(y);
}int Find_Root(int x)
{   while(s[x].f) x=s[x].f;  return x;
}       int main()
{ // IO::setIO("input"); int i,j,n,m; scanf("%d%d",&n,&m);       for(i=1;i<=n;++i)  scanf("%lld",&s[i].v),Pushup(i); for(i=1;i<n;++i) {int x,y; scanf("%d%d",&x,&y); Link_Edge(x,y); con[x][y]=con[y][x]=1; }for(i=1;i<=m;++i) {int op,x,y,z; scanf("%d",&op); if(op==1) {    scanf("%d%d",&x,&y);           if(!con[x][y])  continue;   else {Cut_Edge(x,y);    con[x][y]=con[y][x]=0; }}if(op==2) {    scanf("%d%d",&x,&y); if(Find_Root(x)==Find_Root(y))  continue;        else {con[x][y]=con[y][x]=1;    Link_Edge(x,y);            }}if(op==3) {scanf("%d%d%d",&x,&y,&z);   if(Find_Root(x)!=Find_Root(y)) continue;        Split(x,y);      Up_tag(y,(ll)z);                       }if(op==4)                          {scanf("%d%d",&x,&y);     if(Find_Root(x)!=Find_Root(y)) printf("-1\n"); else {Split(x,y);                    ll dn=s[y].size*(s[y].size+1)/2;                               ll up=(s[y].size+1ll)*s[y].s1[0]-s[y].s2[0];  ll g=gcd(up,dn); printf("%lld/%lld\n",up/g,dn/g);    }   }}return 0;
}

  

BZOJ 3091: 城市旅行 LCT相关推荐

  1. BZOJ 3091 城市旅行 (LCT)

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

  2. bzoj 3091 城市旅行

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

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

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

  4. BZOJ 3531[Sdoi2014]旅行

    BZOJ 3531[Sdoi2014]旅行 题面描述 传送门 题目分析 可以考虑到,如果这个题所有城市都只信一种宗教的话,就是一个sb树剖,直接进行链的查询和修改就能搞定.多个宗教的话,可以有一种暴力 ...

  5. 【BZOJ3091】城市旅行

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

  6. [BZOJ 3531] [Sdoi2014] 旅行 【离线+LCT】

    题目链接:BZOJ - 3531 题目分析 题目询问一条路径上的信息时,每次询问有某种特定的文化的点. 每个点的文化就相当于一种颜色,每次询问一条路径上某种颜色的点的信息. 可以使用离线算法, 类似于 ...

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

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

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

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

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

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

最新文章

  1. 怎样学会单片机?先学什么,怎么入门?
  2. python下载大文件-python requests 下载大文件不完整
  3. 2017-2018-1 20162306 实验五实验报告
  4. 前序中序确认二叉树 7-23 还原二叉树(25 分)
  5. 隐藏画质代码_「图」画质修改工具ReShade放出4.5.0更新:改进对Vulkan等较新API的支持...
  6. 数据挖掘之关联分析六(子图模式)
  7. python anaconda安装_Python - 安装并配置Anaconda环境
  8. axure8.0导出页面打不开问题_excel怎么转pdf?excel打不开?转换成PDF就行了
  9. 文件的删除和文件信息的读取
  10. 使用el-checkbox实现全选,点击失效没有反应
  11. java 线程安全list_JAVA并发编程实战-线程安全性
  12. 【数据库系统】数据库系统的模式分层与数据独立性
  13. SGU 134.Centroid( 树形dp )
  14. iservice封装有哪些方法_对WebService的一些封装技巧总结
  15. python3做答题器_现在很火的答题赢钱游戏,让我来简单教你怎么做自动答题器...
  16. 计算机音乐数字乐谱fade,faded简谱_faded数字简谱
  17. Java实现N元一次方程组求解
  18. 关于信号发生器的功能和参数介绍(一)
  19. 计算机ip怎么换路由器,路由器怎么换ip地址
  20. Unity3D总结记录(四) Unity中控制AudioSourse播放多条不同的声音文件

热门文章

  1. Iintel CPU 漏洞科普和分析
  2. 【幻灯片分享】Siri:I,robot! Siri语音识别系统详解 | 新浪 张俊林 | iOS DevCamp
  3. Netty和Jetty的区别
  4. daysmatter安卓版_倒数日daysmatter安卓下载
  5. C语言课程设计:打字母游戏
  6. mysql-8.0.27-linux版本安装手册,让你一路畅通无阻,2分钟就完成安装
  7. PIFuHD配置记录
  8. 第20章 一些随机波动率模型的近似解
  9. 百度影音小偷PHP版 v2.0
  10. 迅雷是国内最大的云加速服务提供商