チェーンツリーの分割とLCT(続き)

含める

含める

N 110000を定義します

MOD 51061を定義します

名前空間stdを使用。
typedefの長い長いLL。
構造体ノード
{
LL息子[2]、F、C、和、サイズ、LA1、LA2; BOOL SV。
} TR [N]。
;インラインLL CHK(LL X){TR [TR [X] .F] .son [1] == X戻り}
0 [インラインBOOL nroot(LL X){.son [TR [X] .F] TRを返します] == X || TR [TR [X] .F] .son [1] == X;}
インラインLL更新(LLのX){TR [X] .SUM =(TR [TR [X] .son [0]和+。 TR [TR [X] .son [1]和+ T R [X] .C)%MOD; TR [X] .size = T R [T R [X] .son [0]サイズ+ T R [TR [X] .son [1]のサイズ+ 1;}
インラインボイド回転(LL X)
{
CHK(X)^ 1 = W LLのF = T R [X] .F、FF = T R [F] .F、 、息子= TR [X] .son [W]。
R、R LL。
R =息子; R = F; TR [R] .F = R; T R [R] .son [1 ^ W] = R。
R = X; R = FF; TR [R] .F = R; IF(nroot(F))TR [R] .son [CHK(F)] = R。
R = F、R = X; TR [R] .F = R; T R [R] .son R = [W]。
更新(F)、更新(X)。
}
//先乘后加
インラインJIA無効(LLのX、LL d)は{T R [X] .la1 + = D; TR [X] .la1%= MOD;}
インラインボイドチェン(LLのX、LL d)は{TR [ X] .la1 = D; TR [X] .la2 = D; TR [X] .la1%= MOD; TR [X] .la2%= MOD;}
ボイドプッシュダウン(LLのX)
{
IF(TR [X] .sv)
{
TR [X] .sv = 0。
T R [X] .son [0] ^ = TR [X] .son [1] ^ = TR [X] .son [0] ^ = TR [X] .son [1]。
T R [T R [X] .son [0] SV ^ = 1; T R [T R [X] .son [1] SV ^ = 1;
}
IF(!TR [X] .la2 = 1)
{
T R [X] .SUM = T R [X] .la2; TR [X] .C = T R [X] .la2; TR [X] .SUM%= MOD; TR [X] .C%= MOD。
チェン(TR [X] .son [0]、[X] .la2 TR);チェン(TR [X] .son [1]、T R [X] .la2)。
T R [X] .la2 = 1。
}
(TR [x]は.la1)であれば
{
TR [X] .SUM + = TR [X] .la1 * T R [X] .size; TR [X] .C + = TR [X] .la1。
T R [X] .SUM%= MOD; TR [X] .C%= MOD。
JIA(TR [X] .son [0]、TR [X] .la1); JIA(TR [X] .son [1]、T R [X] .la1)。
T R [X] .la1 = 0。
}
}
LLのSTA [N]、LEN。
インラインボイドスプレイ(LLのX)
{
LLのY = X; LEN = 0。
もし(T R [X] .son [0])STA [++ LEN = TR [X] .son [0]。
IF(TR [X] .son [1])STA [++ LEN = TR [X] .son [1]。
STA [++ LEN] = xと;
一方、(nroot(Y))
{
LL W = CHK(Y)^ 1; Y = trの[Y] .F。
(TR [Y] .son [W])STA [++ LEN = TR [Y] .son [W]であれば、
STA [++ LEN]はYを=。
}
(LEN)プッシュダウン(STA [len--])一方、
一方、(nroot(X))
{
LL fが= T R [X] .F、FF = T R [F] .F。
もし回転(X)(nroot(F)!)。
他の回転(CHK(x)は^ CHK(F)X:F?)、(x)を回転させます。
}
}
インラインボイドエース(LL X)
{
(LL Y = 0; X; X = TR [Y = X] .F)用スプレイ(X)、T R [X] .son [1] Yが=、更新(X)。
}
インラインLL FindRootで(LL X)
{
エース(X)、スプレイ(X)。
LL Y = Xの;(TR [Y] .son [0])Y = T R [Y] .son [0]、プッシュダウン(Y)、一方、
Yを返します。
}
インラインボイドmakeroot(LL X)
{
エース(X)、スプレイ(X)。
T R [X] .sv ^ = 1;
}
インラインボイドリンク(LLのX、LLのY)
{
makeroot(X); TR [X] .F = Y。
}
インラインボイド(LLのX、LLのY)をこぼし
{
makeroot(X)。
エース(Y)、スプレイ(X)。
}
インラインボイドカット(LLのX、LLのY)
{
こぼし(X、Y)
T R [X] .son [1] = 0; TR [Y] .F = 0;更新(X)。
}
LL N、M。
INTメイン()
{
scanf関数( "%のLLDの%のLLD"、&N、&M)。
TR [I] .C = TR [I] .SUM = 1、TR [I] .la2 = 1、TR [I] .size = 1(; iは<= N I ++はLL I = 1)のために、
(; iがn <I ++はLL I = 1)のための
{
LLのX、Y; scanf関数( "%のLLDの%のLLD"、およびX&Y)。
リンク(X、Y)
}
のための(LL I = 1; I <= M; iは++)
{
LLのTT、X、Y; scanf関数( "%LLD%LLD%LLD"、&TT、およびX&Y)。
IF(TT == 1)
{
LLのC; scanf関数( "%のLLD"、&C)。
(x、y)がこぼれ。
JIA(X、C)。
}
そうであれば(TT == 2)
{
LLのC; scanf関数( "%のLLD"、&C)。
(x、y)がこぼれ。
チェン(X、C)。
}
そうであれば(TTの== 3)
{
カット(X、Y); scanf関数( "%のLLDの%のLLD"、およびX&Y)。
リンク(X、Y)



(x、y)がこぼれ。
printf( "%LLDする\ n"、TR [X] .SUM)。
}
}
0を返します。
}

おすすめ

転載: www.cnblogs.com/zhangjianjunab/p/11361949.html