効果:指定されたツリーは、各ポイントは、小数点以下の桁を持っている$ kは$で割り切れる進数で構成されているどのように多くのパスを見つけます。
パーティションポイントは、参照は$ 10 ^ A X + B \当量0(MOD \空間K)の$の$ X $の数の変換のために、$ CF713Cの$であってもよいです。
注意を払います
- $ TMP $グローバルとして設定しないでください!
- もし$ \テキスト{Y%のZ == 0} $、その後$ \テキスト{X%Y%Z == X%Z} $
書式#include <iostreamの> の#include <アルゴリズム> 書式#include <cstdioを> する#include <math.h>の 書式#include <設定> 書式#include <マップ> 書式#include <キュー> の#include <文字列> の#include <string.hの> # <ビットセット>含む <;(I ++ = N iは= INT)のための#define REP(I、N) (I = N int型PER(I、N)のための#defineする; I => ; - I) の#defineのHRのputchar(10) の#define PB一back の#define LC(O << 1) の#define RC(LC | 1) の#define中間((L + R)>> 1) の#define LS LC、L、中 の#define RSのRC、ミッド+ 1、R の#define X最初 の#define Yの第二 の#define IOのstd :: IOS :: sync_with_stdio(偽) の#define ENDL '\ n'は 名前空間stdを使用。 typedefの長い長いLL。 typedefのペア<int型、int型> PII。 CONST int型N = 1E5 + 10。 INT和、N、RT、M、P10の[するN]。 INT SZ [N]、MX [N]、VIS [N]、B [N]。 チャーS [N]。 ベクター<INT> G [N]。 ピピ島、ANS1、ANS LL; INT GCD(INT A、INT B){戻りB GCD(B、%のB):;} int型exgcd(int型B INT、INT&X、INT&Y){ int型D。 (B)D = exgcd場合(B、%のB、Y、X)、Y = A / B * X。 そうでなければD =、X = 1、Y = 0。 Dを返します。 } ブールCHK(INT&A、INT&B、INT&P){ // AX = B(MOD P)是否有解 INT X、K、D = exgcd(P、X、K)。 IF(B%D == 0)、A = 1、P / D = B =(B / Dの*第X%のP + P)%のP。 == 1を返します。 } ボイドgetrt(int型のx、int型FA){ MX [X] = 0、SZ [X] = 1。 ための(int型、Y:G [X])であれば(!VIS [Y] && Y = FA){ getrt(Y、X)、SZ [X] + = SZ [Y]。 MX [X] = MAX(MX [x]は、SZ [Y])。 } MX [X] = MAX(MX [x]は、和SZ [X])。 IF(MX [RT]> [X] MX)= xを室温。 } int型のID(INT X){ 戻りLOWER_BOUND(B + 1、B + 1件の+ * B、X)-B。 } マップ<整数、整数> MP [40]。 [I] = GCD(10 ^ H、B Y = J其中// MP [I] [J]记录10 ^ H * X = Y(MOD M)的Y的个数、(MOD B [i])と、 m)の 空隙DFS1(int型のx、int型FA、int型のDEP、ダウンINT){ //求10 ^ DEP * X =(M-ダウン)%Mは int型A = P10 [DEP]、B =(M-ダウン)% M、P = M。 IF(CHK(A、B、P)){ オート&U = MP [ID(P)]。 IF(u.count(B))ANS + = U [B]。 } のための:(!VIS [Y] && Y = FA)IF(int型のY G [X]){ DFS1(Y、X、DEP + 1、((LL)ダウン* 10ll + S [Y])%のM)。 } } アップINT [40]。 ボイドDFS2(int型のx、int型FA、INT DEP){ REP(I、1、* B){ ++ MP [I] [UP [I]]。 } INT TMP [40]。 (VIS [Y] && Y = FA!)なら、{(G [X] yは整数)のための REP(I、1、* B)TMP [i]が最大= [I]、最大[I] =((LL )S [Y] * P10 [DEP] +アップ[I])%のB [i]は、 DFS2(Y、X、DEP + 1)。 REP(I、1、* B)まで[I] = TMP [I]。 } } ボイドDFS3(int型のx、int型FA、ダウンINT、DEP INT、アップINT){ ANS1 + = +アップダウン!。 用(INTのY:G [X])であれば(!VIS [Y] && Y = FA){ DEP DFS3(Y、X、((LL)ダウン* 10の+ S [Y])%のM、+ 1、( (LL)S [Y] * P10 [DEP]最大+)%のM)。 } } ベクトル<整数> Q。 ボイドCALC(INT X){ REP(I、1、* B)MP [I] .clear(); REP(I、1、N)[I-1] P10の[I] = P10の* 10ll%のM。 IF(S [X]%のM == 0)++ ANS1。 {(Q int型のY)用 DFS1(Y、X、1、S [Y]%のM)。 REP(I、1、* B)まで[I] =(S [X] + 10ll * S [Y])%のB [i]は、 DFS2(Y、X、2)。 DFS3(Y、X、(10ll * S [X] + S [Y])%のM、2、(S [X] + 10ll * S [Y])%のM)。 } } ボイドは(int型X)を解く{ VIS [X] = 1。 q.clear(); IF(!VIS [Y])q.pb(Y);(G [x]は整数のY)用 CALC(X) 逆(q.begin()、q.end())。 CALC(X) (!VIS [Y]){もし、(G [X] yは整数)のための MX [RT = 0] = N、和= SZ [Y]。 getrt(Y、0)、(RT)を解きます。 } } ボイドワーク(){ scanf関数( "%D%D%s"は、&N、&M、S + 1)。 ANS = ANS1 = 0。 REP(I、1、n)をG [i]が.clear()、VIS [I] = 0; REP(I、1、n)がS [I] - = '0'; REP(I、2、N){ UをINT、V。 scanf関数( "%d個の%d個"、&U、&V); G [U] .pb(V)。 G [V] .pb(U)。 } (M == 1)リターンのprintf( "%のLLDを\ n"、(LL)N * N)であれば、ボイド(); * B = 0。 REP(I、0、分(N、30))B [++ * B] = M / GCD(P10 [I]、M)。 ソート(B + 1、B + 1 + * B)、* B =一意(B + 1、B + 1 + * B)-b-1。 和= MX [RT = 0] = N、getrt(1,0)、(RT)を解きます。 printf( "%LLDする\ n"、ANS + ANS1 / 2)。 } メインINT(){ P10 [0] = 1。 int型のトン。 scanf関数( "%のD"、&T)。 一方、(t--)ワーク(); }