図階層ツリーメビウス反転+互いに素設定--cf990G

/ * 
ツリーメビウス反転
|ツリーがDを満たす求めるGCD(AU、AV) GCD(AU、AV) ログF(D) 取得する方法
    の数ごとに確立し、図の新しい層を確立200,000すなわち、。新しいマップ   
    プラス側でのUV GCD(AU、AV)図除数層エッジング
    [i]は条件I i番目の層を満たす数を表すfは| GCD([U]、 [V]) 対数、再度互いに素なセット、F更新を検索[i]をマージプロセスで缶、
        fを念頭に置いて、[i]は、この層、対応するIのアクティブノードの数の初期値| GCD([U]このようなケースの[U])を

、最終回答メビウス反転G [D] =シグマ(U [I] * F [I * D])を見つけるために使用される 
 * / 
の#include <ビット/ STDCを++。H >
 使用して 名前空間STD;
 の#define MAXN 200005 INT ファイ[MAXN]、MU [MAXN]、プライム[MAXN]、M;
 BOOL VIS [MAXN];
 無効(INIT)は{ // テーブルMUプレー 
    [ピー。1 ] MUを= [ 1 ] = 1

;
    以下のためにint型 I = 2、I <MAXN; iは++ ){
         場合(!{VIS [i])と
            MU [I] = - 1 ;プライム[++のM] = I; PHI [I] = I- 1 
        } 
        のためのINT J = 1 ; J <= Mであり、j ++ ){
             場合(iは素数* [J]> = MAXN)ブレーク
            VIS [私は *プライム[J] = 1 ;
            もし(I%プライム[j] == 0 ){ 
                PHI [iが素数* [J] = PHI [I] * プライム[J]。
                ミュー[私は = j]と[プライム*]0 ;
                破ります; 
            } 
             PHI [i *が素数[J] = PHI [I] *(プライム[J] - 1)、μは= [iが素数[J] *] - ミューを[I]。
        } 
    } 
} 


int型nは、[MAXN]。
長い 長いF [MAXN]、U [MAXN]、V [MAXN]。
ベクター < INT > [MAXN] VEC。// 每层的边的下标集合

INT F [MAXN]、サイズ[MAXN]。
INT(見つけるINT X){
     戻り?[X] == X X Fを:F [X] = (F [X])を見つけます。
} 
無効ビング(int型 I、int型のu、int型V){
     int型の T1 =検索(U)、T2 = (V)を求めます。
    もし(T1 == T2)のリターン; 
    F [I] + =(長い 長い)サイズ[T1] * サイズ[T2]。
    サイズ[T1] + =サイズ[T2]、F [T2] = T1。
} 


int型のmain(){ 
    INIT()。
    cinを >> N;
    以下のためにint型 i = 1 ; iが<= N; iは++ ){ 
        CIN >> [I]。
        INT J = 1 ; jは* jの<= A [i]は、J ++ 場合([I]%のjは== 0){
                F [J] ++ ;
                もし(![I] / J = J)は、f [[I] / J] ++ ; 
            } 
    } 
    のためにint型 i = 1 ; iがn <; iは++){ // 建立2000000层新图 
        のscanf(" %d個の%のD "、およびU [i]は、&V [I])。
        INT TMP = __gcd([U [I]、[V [I])。
        INT J = 1 J ++; jは* jの<= TMP であれば(TMP%J == 0 ){ 
                VEC [J] .push_back(I)。
                もし(TMP / J!=  J)
                    VEC [TMP / J] .push_back(I); 
            } 
    } 
    // 互いに素なセットを見つける
    ためにint型私は= 1 ; Iは= < 200000を、Iは++ ){
         ためINT J = 0 ; J <VEC [I] .size (); J ++){ // 初期化し、対応する各互いに素なセット
            INTのUu = U [VEC [I]、[J]、VV = V [VEC [I] [J]; 
            F.【のUu] =のUu ; F. [VV] = VV; 
            サイズ【のUu] = 1 ;サイズ[VV] = 1 ; 
        } 
        のためのINT J = 0; J <VEC [I] .size(); J ++){ // 次いで合わせた評価
            int型 UU = U [VEC [i]は[J]]、VV = V [VEC [i]は[J]]; 
            ビング(I、UU、VV); 
        } 
    } 
    // 反演+输出
    int型、D = 1 ; D <= 200000 ; D ++ ){
         長い 長い ANS = 0 以下のためにint型 i = 1 ; iが* D <= 200000 ; iは++ 
            ANS + =(長い 長い)MU [i]は* F [i *がD]。
        もし(ANS!= 0 
            はcout << D << "  " << ANS <<' \ nを' ; 
    } 
}

 

おすすめ

転載: www.cnblogs.com/zsben991126/p/11117356.html