BZOJ 3091: 城市旅行 lct 期望 splay

Posted 鲸头鹳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
View Code

 

以上是关于BZOJ 3091: 城市旅行 lct 期望 splay的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ3091: 城市旅行

BZOJ3091 城市旅行 LCT

bzoj3091城市旅行 LCT区间合并

BZOJ[3091] 城市旅行

bzoj3091: 城市旅行

BZOJ3091: 城市旅行