Description
Input
Output
Sample Input4 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 Output16/3
6/1
HINT
For all data meet 1<=n<=50,000 1<=m<=50,000 1<=ai<=10^6 1<=d<=100 1<=u,v<=n
The disgusting dynamic tree maintains a variety of information. It is not difficult to find ans=σai*i* (len-i+1). We maintain several values on the splay tree:
sumv=σai*i* (len-i+1) lsum=σai*irsum=σai* (len-i+1) Sum=σai is not difficult to maintain the relationship of several variables, the lazy mark when the quick calculation of σi* (len-i+1) and Ōi on the line.
Notice that flip has to swap the lsum and rsum of the two subtrees.
#include <cstdio>#include<cstring>#include<algorithm>#include<cctype>#defineLC Ch[x][0]#defineRC Ch[x][1]#defineRep (i,s,t) for (int i=s;i<=t;i++)#defineDwn (i,s,t) for (int i=s;i>=t;i--)#defineren for (int i=first[x];i!=-1;i=next[i])using namespacestd;Const intBuffersize=1<< -;Charbuffer[buffersize],*head,*Tail;inlineCharGetchar () {if(head==tail) { intL=fread (Buffer,1, Buffersize,stdin); Tail= (Head=buffer) +l; } return*head++;} InlineintRead () {intx=0, f=1;CharC=Getchar (); for(;! IsDigit (c); C=getchar ())if(c=='-') f=-1; for(; IsDigit (c); C=getchar ()) x=x*Ten+c-'0'; returnx*F;} typedefLong Longll;Const intmaxn=50010; ll F[MAXN],SUMV[MAXN],SUM[MAXN],LSUM[MAXN],RSUM[MAXN],S[MAXN],ADDV[MAXN],VAL[MAXN];intpre[maxn],fa[maxn],ch[maxn][2],FLIP[MAXN];voidADD (intX,ll v) { if(!v| |! Xreturn; SUMV[X]+=v*F[s[x]]; LSUM[X]+=v* (1+S[X]) *s[x]/2; RSUM[X]+=v* (1+S[X]) *s[x]/2; SUM[X]+=v*s[x];}voidMaintain (intx) {if(!x)return; S[X]=s[lc]+s[rc]+1; SUM[X]=sum[lc]+sum[rc]+Val[x]; SUMV[X]=sumv[lc]+sumv[rc]+lsum[lc]* (s[rc]+1) +rsum[rc]* (s[lc]+1) +val[x]* (s[lc]+1) * (s[rc]+1); LSUM[X]=lsum[lc]+lsum[rc]+val[x]* (s[lc]+1) +sum[rc]* (s[lc]+1); RSUM[X]=rsum[rc]+rsum[lc]+val[x]* (s[rc]+1) +sum[lc]* (s[rc]+1); ADD (X,addv[x]);}voidPushdown (intx) {if(Flip[x]) {swap (LC,RC); Swap (LSUM[LC],RSUM[LC]); Swap (LSUM[RC],RSUM[RC]); FLIP[LC]^=1; flip[rc]^=1; FLIP[X]=0; } if(Addv[x]) {val[x]+=addv[x];addv[lc]+=addv[x];addv[rc]+=Addv[x]; ADD (Lc,addv[x]); ADD (Rc,addv[x]); Addv[x]=0; }}voidRotateintx) {inty=pre[x],z=pre[y],d=ch[y][0]==x; Ch[y][d^1]=CH[X][D];p re[ch[x][d]]=y; ch[z][ch[z][1]==y]=x;pre[x]=Z; CH[X][D]=y;pre[y]=X;maintain (y);}intS[maxn],top;voidSplay (intx) { for(intI=x;i;i=pre[i]) s[++top]=i; if(top!=1) fa[x]=fa[s[top]],fa[s[top]]=0; while(top) Pushdown (s[top--]); while(pre[x]) rotate (x); Maintain (x);}voidAccessintx) { for(inty=0; x;x=Fa[x]) {splay (x);p re[ch[x][1]]=0; fa[ch[x][1]]=x; ch[x][1]=y;pre[y]=x;maintain (y=x); }}voidMakeroot (intx) {access (x); splay (x); Flip[x]^=1; Maintain (x);}intFindintx) {access (x); splay (x); while(ch[x][0]) x=ch[x][0]; returnx;}voidLinkintXinty) {makeroot (x); Fa[x]=y;}voidCutintXinty) {makeroot (x); Access (y); splay (y); if(s[y]==2) {pre[ch[y][0]]=0; ch[y][0]=0; Maintain (y); }}ll gcd (ll x,ll y) {return!Y?X:GCD (y,x%y);}voidQueryintXinty) {makeroot (x); Access (y); splay (y); ll Len=s[y]-1; Len= (len+1) * (len+2)/2; ll ans=sumv[y],t=gcd (Len,ans); printf ("%lld/%lld\n", ans/t,len/t);}voidUpdateintXintY,ll v) {makeroot (x); Access (y); splay (y); Addv[y]+=v; ADD (y,v);}intMain () {intN=read (), m=read (); f[1]=1; Rep (I,2, N) f[i]=f[i-1]+ (LL) i* (i-1)/2+i; Rep (I,1, N) val[i]=read (); Rep (I,1, N-1) Link (read (), read ()); while(m--) { intT=read (), X=read (), y=read (); if(t==1)if(Find (x) = =find (Y)) cut (x, y); if(t==2)if(Find (x)! =find (Y)) Link (x, y); if(t==3) {ll v=read (); if(Find (x) = =find (Y)) update (X,Y,V); } if(t==4) { if(Find (x) = =find (Y)) query (x, y); ElsePuts"-1"); } } return 0;}
View Code
BZOJ3091: City Trip