FFT第四質問!
夏には、ときにのみ点在し、その後、マージ暴力がマージ...水がなくなっています...
実際には、2つのパスの組み合わせた長さは、コンボリューション処理まあ、自己畳み込みへの完全なパスについてのたびに統計があります。
最初のコンボリューションの固定範囲で。T Aを。そして、怠惰なことはありません、それぞれ最大重量により-2服用は範囲に行きました。
#include <ビット/ STDC ++。H> constの ダブル PI = ACOS( - 1.0 )。 ストラクト複雑{ ダブルRを、I。 ボイドクリア(){式中、Rは=私は= 0.0 。} (複合二重 R = 0、ダブル I = 0 )R(R)、I(I){} 複合演算子 +(CONST複合&P)のconst { 戻り錯体(R + PR、I + PI)。} 複合演算子 - (CONST複合&P)のconst { 返す( - PR、I - R複合PI)を。} 複合演算子 *(CONST複合&P)のconst { 戻り錯体(R * PR - I + I * PI、R * PI * PR)を、} }。 ボイド FFT(複合*、INT N、int型 PD、INT * R){ ため(INT iは= 0 ; iは<N; I ++ ) 場合(I < R [i])と STD ::スワップ([I]、[R [I])。 用(int型ミッド= 1 ;ミッド<N;中間<< = 1 ){ コンプレックスWN(COS(PI /ミッド)、PD *罪(PI / MID)); 用(int型 L =ミッド<< 1、J = 0 ; J <N + J = {L) 錯体W(1.0、0.0 )。 用(int型のk = 0 ; K <ミッド; * W = W K ++、WN){ 複合uは [K + j]を= V = W * [K + J + 中間]。 [K + J] = U + V。 [K + J +中間] = U - 、V。 } } } もし(PD < 0 ) のための(INT iは= 0、I <N; I ++ ) [I] =コンプレックス([I] .R / N [i]は.I / N)。 } #define LL長い長いです CONST INT N = 2E5 + 7 。 整数nは、SZ [N]、maxsz [N]、根、totsz。 std ::ベクトル < 整数 > VEC [N]。 INT プライム[N]、PRIN。 BOOL VIS [N] である[N]。 LL CNT [N]、CCNT [N]。 INT DIS [N]、R [N]。 錯体A [N]。 INT 限界、L。 ボイドのinit(){ ため(INT iは= 2、I <N; I ++ ){ 場合(!あるプライム[I])[++ PRIN] = I。 以下のために(INT J = 1 ; J <= PRIN && iが素数[j]を* <N; J ++ ){ される [i *が素数[J] = 1 。 もし(I%プライム[J] == 0)ブレーク。 } } } インラインBOOL chkmax(INT&、int型 B){ 戻り <bは?A = B、1:0 。} ボイド getroot(INT U、INT FA){ SZ [U] = 1。maxsz [U] = 0 ; 用(INT V:VEC [U]){ 場合(V == FA || VIS [V])続けます。 getroot(V、U); C [U] + = C [V]。 chkmax(最大[U]と、C [V])。 } chkmax(maxsz [U]、totsz - SZ [U])。 もし(maxsz [U] <maxsz [ルート])ルート= U。 } INT F [N] TTO、価値があります。 ボイド getdis(INT U、INT FA){ F [ ++ TTO] = Y [U]。 ヴァル = STD :: MAX(ヴァル、F [TTO])。 用(INT V:VEC [U]){ 場合(VIS [V] || V == FA)続けます。 DIS [V] = DIS [U] + 1 。 getdis(V、U); } } 空 CAL(あなたと、あなたは、dはあなたが選びます){ tto = 0; DIS [U] = D。 ヴァル = 0 ; getdis(U、0 ); 以下のために(int型私は= 1 ; I <=っとし; I ++ ) CCNT [F [I]] ++ ; 限界 = 1、L = 0 。 一方、(限界<= 2 * ヴァル) 限界 << = 1、L ++ 。 用(INT iは= 0を I ++; I <限界) R [i]は = R [I >> 1 ] >> 1 | ((I&1)<<(1 - 1 ))。 用(INT iは= 0を I ++; I <限界) A [i]は =コンプレックス((二重)CCNT [i]が、0.0 )。 FFT(A、限界、1 、R) 用(INT iは= 0を I ++; I <限界) [I] = A [i]が* A [i]は、 FFT(A、限界、 - 1 、R)。 用(INT iは= 1、I ++; I <限界) CNT [I] + = OPT *(LL)(A [i]が.R + 0.5 )。 以下のために(int型私は= 1 ; I <=っとし; I ++ ) CCNT [F [I]] - 。 } ボイド解く(INT U){ 高さ[I] = 1 。 CAL(U、0、1 )。 用(INT V:VEC [U]){ 場合(VIS [V])続けます。 CAL(中1 - 1 )。 totsz = C [V]。 ルート = 0 ; getroot(V、0 ); (ルート)を解きます。 } } INT メイン(){ 初期化(); scanf関数(" %のD "、&N) 以下のために(INT iが= 1 ; I <N; I ++ ){ int型、U、V。 scanf関数(" %D%D "、&U&V); ケース[U] .push_back(A)。 ケース[] .push_back(S) } maxsz [ルート = 0 ] = N。 totsz = N。 getroot(1、0 ); (ルート)を解きます。 LL ANS = 0 。 以下のために(INT iは= 1 ; I <= PRIN; I ++ ){ 年 + = CNT [プレミアム[I]]; } 合計ちゃう = 1LL * N *(N - 1 )。 printf(" %.7f \ N "、1.0 * ANS / 合計)。 リターン 0 ; }