羅区[P4245] [テンプレート] NTT任意係数

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を返します。
}           

  

おすすめ

転載: www.cnblogs.com/guangheli/p/11917733.html