NTTのトライモード番号、気持ちは$?$を書くことは難しいことではありません
コードは、学ぶ https://www.cnblogs.com/Mychael/p/9297652.html
コード:
#include <ビット/ STDC ++ H> の#define SIZE 400005 の#defineっ長い長 の#define setIO(S)(S ".IN"、 "R"、STDIN)freopenは 名前空間stdを使用します。 インラインLL qpow(MOD LL LL X、LLのY) { LL再= 1LL。 (Y&1)再=再* X%モッド場合(Y >> = 1、X = X * X%のMod; Y、X%= MOD)のために、 再を返します。 } INT PR [3] = {469762049,998244353,1004535809}。 構造体ポリ { G、MOD、A [SIZE] INT。 ボイドNTT(INT *、INT LEN、INTフラグ) { int型I、J、K、ミッド。 以下のために(私は= K = 0; I <LEN; ++ I) { IF(I> K)スワップ([I]、[K])。 用(J = LEN >> 1;(K ^ = J)<J; J >> = 1)。 } ため(MID = 1;ミッド<lenを、中間<< = 1) { int型WN = qpow(G、(MOD-1)/(中間<< 1)、MOD)。 IF(フラグ== - 1)WN = qpow(WN、モッド-2、MOD)。 ための式(I = 0; iは<lenを、I + =中間<< 1) { = 1ワットINT。 (; J <中間J = 0 ++ j)のための { int型のx = [I + J]、Y = 1LL * W * [I + J +中間]%のMod。 [I + J] = 1LL *(X + Y)%MOD、[I + J +中間] =(X-Y + MOD)%のMod。 = 1LL * W、WN%モッドW。 } } } (フラグ== - 1)であれば { INT REV = qpow(LEN、モッド-2、MOD)。 { ための式(I = 0; iは<lenの; ++ I)[I] = 1LL * [I] *のREV%モッド。 } } } NTT [3]。 LL ANS [SIZE]。 INT F [SIZE]、G [SIZE]、B [SIZE]、deg1、deg2、DEG、メリーランド州; ; INV(LL N、P LL){戻りqpow(N%のP、P-2、P)LL } LL MUL(-1,11,11- B、LL P) { LL再= 0。 用(; B; B >> = 1、A =(A + A)%P)IF(B&1)再=(RE + A)%のP。 再を返します。 } ボイドCRT() { DEG = deg1 + deg2。 LL、B、C、T、K、M = 1LL * PR [0] * PR [1]。 LL INV1 = INV(PR [1]、PR [0])、INV0 = INV(PR [0]、PR [1])、INV3 = INV(M%PR [2]、PR [2])。 以下のために(INT I = 0; I <=゜; ++ I) B = NTT [1] .A [I]。 A = NTT [0] .A [I]。 C = NTT [2] .A [I]。 T =(MUL(* PR [1]%M、INV1、M)+ MUL(B * PR [0]%M、INV0、M))%M。 K =((CT%PR [2])%PR [2] + PR [2])%PR [2] * INV3%PR [2]。 ANS [I] =((K%MD)*(M%MD)%MD + T%MD)%MD。 } } ボイドCONV() { int型のn = 1。 一方、(N <=(deg1 + deg2))N << = 1。 (++ U; U <= 2 INT U = 0)のための { NTT [U] .G = 3。 NTT [U]の.mod = PR [U]。 以下のために(INT iが= 0; I <= deg1; ++ I)NTT [U] .A [I] = F [i]は、 以下のために(INT iが= 0; I <= deg2; ++ I)B [I] = G [i]は、 (INT I = deg2 + 1、I <N; ++ i)に対するB [I] = 0; NTT [U] .NTT(NTT [U] .A、nは、1)。 NTT [U] .NTT(B、nは、1)。 (I = 0 INT; I <N; ++ i)に対するNTT [U] .A [I] = 1LL * NTT [U] .A [I] * B [I]%PR [U]。 NTT [U] .NTT(NTT [U] .A、N、-1); } } int型のmain() { // setIO( "入力")。 scanf関数( "%D%D%D"、&deg1、&deg2、&MD)。 以下のために(INT iが= 0; I <= deg1; ++ I)のscanf( "%d個"、&F [I])。 scanf関数( "%のD"、&G [i])と(++ I; I <= deg2 INTがI = 0)ため、 CONV(); CRT()。 以下のために(INT iが= 0; I <=゜; ++ I)のprintf( "%のLLD"、ANS [I])。 0を返します。 }