BZOJ 3091: 城市旅行 lct 期望 splay

https://www.lydsy.com/JudgeOnline/problem.php?id=3091

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

看题解吧,没什么好解释的。。。。板子题,

我觉得以后我写lct都可以像这样专门写个rev和add的函数出来,很好用。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<queue>
  7 using namespace std;
  8 const int maxn=50010;
  9 int n,m;
 10 int fa[maxn]={},ch[maxn][2]={};
 11 long long siz[maxn]={},val[maxn]={},sum[maxn]={};
 12 long long lsum[maxn]={},rsum[maxn]={};
 13 long long num[maxn]={};long long ad[maxn]={};
 14 int rev[maxn]={};int sta[maxn]={},tail=0;
 15 inline void updata(int x){
 16     sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+val[x];
 17     siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
 18
 19     lsum[x]=lsum[ch[x][0]]+lsum[ch[x][1]]+(sum[ch[x][1]]+val[x])*(siz[ch[x][0]]+1);
 20     rsum[x]=rsum[ch[x][1]]+rsum[ch[x][0]]+(sum[ch[x][0]]+val[x])*(siz[ch[x][1]]+1);
 21
 22     num[x]=num[ch[x][0]]+num[ch[x][1]]
 23     +lsum[ch[x][0]]*(siz[ch[x][1]]+1)
 24     +rsum[ch[x][1]]*(siz[ch[x][0]]+1)
 25     +val[x]*(siz[ch[x][0]]+1)*(siz[ch[x][1]]+1);
 26 }
 27 inline long long hex(long long x){return x*(x+1)/2;}
 28 inline long long hex2(long long x){return x*(x+1)*(x+2)/6;}
 29 void Add(int x,long long v){
 30     ad[x]+=v; sum[x]+=siz[x]*v; val[x]+=v;
 31     lsum[x]+=hex(siz[x])*v;
 32     rsum[x]+=hex(siz[x])*v;
 33     num[x]+=hex2(siz[x])*v;
 34 }
 35 void Rev(int x){
 36     swap(ch[x][0],ch[x][1]);
 37     swap(lsum[x],rsum[x]);
 38     rev[x]^=1;
 39 }
 40 inline void downdata(int x){
 41     if(rev[x]){
 42         if(ch[x][0])Rev(ch[x][0]);
 43         if(ch[x][1])Rev(ch[x][1]);
 44         updata(x);
 45         rev[x]=0;
 46     }
 47     if(ad[x]){
 48         if(ch[x][0])Add(ch[x][0],ad[x]);
 49         if(ch[x][1])Add(ch[x][1],ad[x]);
 50         updata(x);
 51         ad[x]=0;
 52     }
 53 }
 54 inline bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
 55 void rotate(int x){
 56     int y=fa[x];int fy=fa[y];
 57     int l=ch[y][0]==x?0:1;int r=l^1;
 58     if(!isroot(y)){
 59         if(ch[fy][0]==y)ch[fy][0]=x;
 60         else ch[fy][1]=x;
 61     }
 62     fa[ch[x][r]]=y;fa[y]=x;fa[x]=fy;
 63     ch[y][l]=ch[x][r];ch[x][r]=y;
 64     updata(y);
 65 }
 66 void Splay(int x){
 67     int y,fy,w=x;sta[++tail]=x;
 68     while(!isroot(w)){ sta[++tail]=fa[w]; w=fa[w]; }
 69     while(tail)downdata(sta[tail--]);
 70     while(!isroot(x)){
 71         y=fa[x];fy=fa[y];
 72         if(!isroot(y)){
 73             if((ch[fy][0]==y)^(ch[y][0]==x)) rotate(x);
 74             else rotate(y);
 75         }
 76         rotate(x);
 77     }updata(x);
 78 }
 79 void Access(int x){
 80     int y=0;
 81     while(x){
 82         Splay(x);ch[x][1]=y;
 83         updata(x);
 84         y=x;x=fa[y];
 85     }
 86 }
 87 int findfa(int x){
 88     Access(x);Splay(x);
 89     while(ch[x][0])x=ch[x][0];
 90     return x;
 91 }
 92 void Reverse(int x){
 93     Access(x);Splay(x);
 94     Rev(x);
 95 }
 96 void Cut(int x,int y){
 97     Reverse(x);Access(y);Splay(y);
 98     if(ch[y][0]==x&&!ch[x][1]){fa[x]=0;ch[y][0]=0;updata(y);}
 99 }
100 void Link(int x,int y){
101     Reverse(x);
102     fa[x]=y;
103 }
104 long long mgcd(long long x,long long y){
105     long long z;
106     while(y){
107         z=x%y;x=y;y=z;
108     }return x;
109 }
110 int main(){
111     //freopen("a.in","r",stdin);
112     //freopen("a.out","w",stdout);
113     scanf("%d%d",&n,&m);
114     for(int i=1;i<=n;i++){scanf("%lld",&val[i]);siz[i]=1;sum[i]=lsum[i]=rsum[i]=num[i]=val[i];}
115     int x,y,op;long long v,aa,bb;
116     for(int i=1;i<n;i++){
117         scanf("%d%d",&x,&y); if(findfa(x)!=findfa(y))Link(x,y);
118     }
119     for(int i=1;i<=m;i++){
120         scanf("%d%d%d",&op,&x,&y);
121         if(op==1){
122             if(findfa(x)==findfa(y))Cut(x,y);
123         }
124         else if(op==2){
125             if(findfa(x)!=findfa(y))Link(x,y);
126         }
127         else if(op==3){
128             scanf("%lld",&v);
129             if(findfa(x)==findfa(y)){
130                 Reverse(x);Access(y);Splay(y);
131                 Add(y,v);
132             }
133         }
134         else{
135             if(findfa(x)!=findfa(y)){printf("-1\n");}
136             else{
137                 Reverse(x);Access(y);Splay(y);
138                 aa=num[y];bb=hex(siz[y]);
139                 v=mgcd(aa,bb);
140                 printf("%lld/%lld\n",aa/v,bb/v);
141             }
142         }
143     }
144 }

原文地址:https://www.cnblogs.com/137shoebills/p/8661650.html

时间: 2024-11-13 08:04:53

BZOJ 3091: 城市旅行 lct 期望 splay的相关文章

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

3091: 城市旅行 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1454  Solved: 483[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&l

BZOJ 3091 城市旅行 Link-Cut-Tree

警告:此题不可以使用cout进行输出,只能用printf,否则RE!亲测!! 题目大意:给定一棵树,每个点有一个点权,提供四种操作: 1.删除两点之间的连边 不存在边则无视 2.在两点之前连接一条边 两点已经联通则无视 3.在两点之间的路径上所有点的点权加上一个数 两点不连通则无视 4.询问两点之间路径上任选两点路径上的点权和的期望值 前三个操作都很基础 但是第四个东西--这啥玩应这是-- 首先这个期望值等于路径上所有无序点对路径上权值和的平均值 还是很抽象?没关系,拿样例说话 样例第一个询问

【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区间合并 前三个操作都是LCT的基本操作,可以LCT水过:重点在于第四个操作. 考虑一个长度为n的序列,它的子区间个数为$\sum\limits_{i=1}^ni=\frac{n(n-1)}2$,只需要维护每个子区间的长度之和即可. 考虑如果已经知道了左右子树的信息以及当前节点信息,如何更新当前子树的信息.需要解决

【LCT】BZOJ3091 城市旅行

3091: 城市旅行 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1927  Solved: 631[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&l

[bzoj2816][ZJOI2012]网络(LCT,splay)

传送门 题解 话说以前还真没见过用LCT只维护一条链的……好像除了树点涂色那题…… 先看一下题目规定的两个性质 对于任意节点连出去的边中,相同颜色的边不超过两条. 图中不存在同色的环,同色的环指相同颜色的边构成的环. 很明显了,同一种颜色肯定是由几条链组成的(虽然我根本没有发现) 然后又要查询边权和维护路径……直接上LCT吧 然后颜色数很少啊……每一个颜色开一个LCT好了 更改权值的话在每一个LCT上splay一下 修改颜色的话在原来的LCT中cut,新的LCT中link 查询路径直接split

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

题目链接:BZOJ - 3531 题目分析 题目询问一条路径上的信息时,每次询问有某种特定的文化的点. 每个点的文化就相当于一种颜色,每次询问一条路径上某种颜色的点的信息. 可以使用离线算法, 类似于“郁闷的小 J ” 那道题目.将各种操作和询问按照颜色为第一关键字,时间为第二关键字排序. 那么修改颜色的操作就相当于在原颜色中是删点,在新颜色中是加点. 处理完一种颜色的操作后,要将这个颜色的点都做一次删除操作,这样,对于处理下一种颜色,树就又是空的了. 这种题,思考的时候有点晕,写代码的时候非常

BZOJ 2843: 极地旅行社 lct splay

http://www.lydsy.com/JudgeOnline/problem.php?id=2843 https://blog.csdn.net/clove_unique/article/details/50992341 和之前那道题lct求两点距离用lca不同,这道题因为给的边的两个端点是没有顺序的(没法直接按照给的点直接将某个点连到树上),所以bridge需要区间翻转的操作,因为splay维护的是链,所以区间翻转相当于将叶子变成了根,根变成叶子(链翻转过来),然后再把此时的根(x)连到y

P4842 城市旅行

$ \color{#0066ff}{ 题目描述 }$ W国地人物博,有n座城市组成,共n-1条双向道路连接其中的两座城市,且任意两座城市都可相互到达. 风景秀美的w国吸引了无数慕名而来的游客,根据游客对每座城市的打分,我们定义第i座城市的美丽度为\(a_i\).一次从城市x到城市y的旅行,所获得的的偷悦指数为从城市x到城市y所有城市的美丽度之和(包括X和y).我们诅义这个值为H(x,y). 现在小A在城市X,Sharon在城市Y,他们想知道如果在城市X到城市Y之间的所有城市中任选两座城市x和y(

bzoj 3531 [Sdoi2014]旅行(树链剖分,线段树)

3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 876  Solved: 446[Submit][Status][Discuss] Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰.为了方便,我们用不同的正整数代表 各种宗教,  S国的居民常常旅行.旅行时他们总