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 }