문제 :
숫자 $ N-1 $ 다항식 $의 F로 알려져있다 (X) $ 다항식 $의 G를 찾을 수 (X) $되도록 $ F (X) * G (X) \ 당량 1 $ ($ 개조 X ^ {N } $)의 모든 동작은 998 244 353 다이 감각 실시
어떻게?
약간의 분석이기 위하여 :
$ F (x)는 $는 하나, 단지 하나의 후 $ G (X) $ 즉, 그 반대면에서 $ F (x)가 $이면
그럼 다항식 $ H를 알고있는 경우 (x)를 만족 $ $ F (X) * H (X) \ $ 1 당량 ($ 개조 $ X ^ {$ \ FRAC {N} {2}} $)
물론, 필요에 따라, 반면 : $ F (X) * G (X) \ $ 1 당량 ($ 개조 $ X ^ {$ \ FRAC {N} {2}} $)
제공하기 위해, 공식 공식을 저장합니다 :
$ F (X) (G (X) -H (X)) \ 당량 $ 0 ($ 개조 $ X ^ {$ \ FRAC {N} {2}} $)
그런 다음이
$ G (X) -H (X) \ 당량 $ 0 ($ 개조 $ X ^ {$ \ FRAC {N} {2}} $)
광장의 양쪽을 얻을 수있다 :
$ (G (X) -H (X)) ^ {2} \ 당량의 0 $ ($ 개조 $ $ X ^ {N} $)
도 확장 :
$ G (X) ^ {2} + H (X) ^ {2} -2G (X) H (X) \ 당량 $ 0 ($ 개조 $ $ X ^ {N} $)
양측은 달러 (A $) F (x)의 $를 가지고 :
$ F (x)는 G (X) ^ {2} + F (X) H (X) ^ {2} -2F (x)는 G (X) H (X) \ 당량 ($ 0 $ 개조 $ $ X ^ {N} $)
요구에 따라, $ F (x)는 G (X) \ $ 1 당량 ($ 개조 $ $ X ^ {N} $)
그래서 방정식을 단순화 할 수 있습니다 :
$ G (X) + F (X) H (X) ^ {2} -2H (X) \ 당량 $ 0 ($ 개조 $ $ X ^ {N} $)
조옮김, 제공 :
$ G (X) \ 당량 2H (X) - F (X) H (X) ^ {2} $ ($ 개조 $ $ X ^ {N} $)
이것은 해결 될 수 배
코드 :
#INCLUDE <cstdio> #INCLUDE <cmath> #INCLUDE <CString을> #INCLUDE <cstdlib> #INCLUDE <iostream> #INCLUDE <알고리즘> #INCLUDE <큐> #INCLUDE <적층> #DEFINE LL 긴 긴 사용 스페이스 성병; CONST LL 모드 = 998244353 ; LL의 F [ 100005 ]; int로 [(에 1 << 20 ) + (5) ]; 구조체 노드 { LL g의 [ 100005 ]; INT 렌; } 이제, 라스; INT의 N; INT LIM = 1 , L = 0 ; LL의 pow_mul (LL의 X, Y의 LL) { LL의 RET = 1 ; 반면 (Y) { 경우 (Y & 1 ) = RET RET * X %의 모드; X = X * X 모드 %, Y = >> 1 ; } 반환 RET를; } 공극 NTT (LL * A, INT 렌 의 INT K) { LL의 INV = pow_mul (LEN, 모드 - 2 ); 대 ( INT I = 0 ; I <렌; 내가 ++)경우 (ⅰ < 스왑 [I]로) (a [i]를, A [[I]로]); 위한 ( int로 I = 1 ; i가 LEN <나는 << = 1 ) { LL W0 = pow_mul ( 3 (모드 - 1 ) / (I << 1 )); 대 ( INT의 J = 0 ; J <LEN] = J + (I << 1 )) { LL w = 1 ; 위한 ( INT O = 0 ; O <I, O ++ = *를 W0의 %의 w w 모드) { LL의 W1 모드;= A [J + O]는, W2는 [j는 + O + I * % w = A [J + O] = (W1 + W2) % 모드, [J + O + I] = ((W1-W2) 모드 % + 모드) %의 모드; } } } 경우 - (K == 1 ) { 위해 ( int로 I = 1 ; i가 <(LEN은 >> 1 스왑 (a [i]를, A [len- 난 ++)) I])를; 위한 ( int로 I = 0 A [I]은 [I] * %의 INV의 =; 나는 LEN <I가 ++)의 모드; } } A [(LL 1 << 20 ) + (5) , (B)의 [( 1 << 20 ) + (5) , (C)의 [( 1 ) +<< 20 5 ]; 공극 해결 ( INT의 DEP) { 경우 (DEP == 1 ) { now.g [ 0 ] = pow_mul (F [ 0 ], 모드 - 2 ); now.len = 1 ; 라스 = 지금; 반환 ; } INT NXT = (DEP + 1 ) / 2 ; (NXT) 해결; LIM = 1 , L = 0 ; 반면 (LIM <= 2 * DEP) LIM << = 1 , L ++; 위한 ( int로 I = 1 ; I ++는, 난 <LIM)에 [I] = ((에 [I >> 1 ] >> 1 ) | ((I & 1 ) << 1- ( 1 ))); 위한 ( int로 I = 0 ; I는 <LIM; 내가 ++)이 [I] = B를 [I] = 0 ; 위한 ( int로 I = 0 ; I <가 DEP, 난 ++) A [내가] = F의 [I]; 위한 ( int로 I = 0 ; I는 NXT를 <; 내가 ++) B [I] = las.g [I]; NTT (a, LIM, 1 ), NTT (b, LIM, 1 ); 대 ( INT I = 0나는 <LIM; 내가 ++) C는 [I]은 [I]가 * B [I] % 모드에서 * B [I] = %의 모드; NTT (c, 임 - 1 ); now.len = DEP; 위한 ( int로 I = 0 ; I <가 DEP, 내가 ++) now.g [I] = (( 2 * las.g [I] -c [I]) 모드 % + 모드) %의 모드; 라스 = 지금; } INT 의 main () { 는 scanf ( " %의 D ' , N); 위한 ( int로 I = 0 는 scanf (; i가 N이 <I ++) " %의 LLD ' , F [I]를); (N) 해결; 대한 ( INTI = 0 ; I <N은, 내가 ++)의 printf ( " %의 LLD " , now.g [I]); 의 printf ( " \ n을 " ); 반환 0 ; }