BZOJ 4197:の形[Noi2015] DP +寿司の夕食プレス素因数分解

神は非常に疑問 -      

候補者の数が2プライムケースを持つことができないので、1が選出された場合、その素因数のために、二人は品質係数によって、任意の数の倍数を選択することができません。    

その後、我々は1から500までの数のために、より大きな$ \ sqrtの500個の$素因数(2、500以上のその製品を)持っていることだけが可能であることがわかりました 

そして、8つだけの素因数の総数のではない以上$ \ sqrtの500 $、そうすることができ、圧力のようなこれらの8つの要因の品質。   

のは、すべての数字は$ \ eqslant 30 $であると仮定しましょう、つまり、すべての素因数は$ leqslant \ sqrtの500 $です。 

定義された状態DP [I] [J]素因数の最初の個々のセットは$ I $から選択されていることを示し、二人目は、$ J $の素因数のセットから選択されます。   

そして、直接$のDPを更新[I | STA] [J] + = DP [I] [J] $(STA及びk互いに素)   

同様に第二次元の。 

私たちは、スクロール配列を使用しているので、そうもF1定義[I] [J]、F2 [i] [j]が第一/第二の人と二人/個々の第1の状態で個々のプログラムの数を表します。   

この転送はそれを成し遂げるの後、我々は定性的要因の$ \ sqrtの500 $の状況よりも大きいを追加することを検討します:   

これは$ X $の品質係数を行い、その後、デジタルは$ X $、明らかにこれらの数字は一人だけが、素因数を選択することができます含めるがあるでしょう。  

私たちは、スタート位置に直接、その後の更新にそのF1 [I] [J]、F2 [I] [J]の上に従って、そのF1ので、このセクション= F2 = dpと、通常のDPの残りの部分。 

この場合には処理されたとき、私たちは二つの数字が選択されていない差し引く必要があります。   

最后DP '[i]は[J] = F1 [I] [J] + F2 [I] [J] -dp [I] [J]。   

コード: 

#include <ビット/ STDC ++ H>    
に#define N 703   
の#define LL長い長
の#define setIO(複数可)freopenは(S ".IN"、 "R"、STDIN)
名前空間stdを使用。   
int型のn;  
int型poww [N]。
LLは、モッズANS;   
LLのDP [N] [N]、F1 [N] [N]、F2 [N] [N]。       
int型のP [13] = {0,2,3,5,7,11,13,17,19,23}。      
構造体データ
{ 
    INT NUM、BI、STA。
} [N]。     
ブールCMP(データA、データB)
{ 
    リターンa.bi <b.bi。        
} 
ボイドのinit(INT NUM)
{    
    int型I、J、V = NUM、BI = 0。    
    ため(I 1 =; I <= 8; ++ i)が     
    {                                                  
        IF(v%でのP [I] == 0) 
        {     
            [NUM] .sta | = poww [i]は、    
            一方、(v%でのP [I] == 0)V / P = [I]。    
        } 
    }     
    もし(V> 1)BI = V。    
    [NUM] .BI = BI。    
    [NUM] .nu​​m = NUM。            
} 
int型のmain()
{ 
    // setIO( "入力")。   
    私は、jはint型。
    scanf関数( "%D%LLD"、&N、&MOD)。                              
    以下のための(iは= 1; I <= 12; ++ i)はpoww [I] =(1 <<(I-1))。      
    ための式(I = 2、I <= N; ++ I)のinit(I)。                                         
    ソート(+ 2、+ 1 + N、CMP)。     
    DP [0] [0] = 1LL。    
    以下のために(I 2 =、iが<= N; ++ i)が
    { 
        IF(!私== 2 || [I] .BI || A [i]の.BI = [I-1] .BI)
        {
            memcpyの(F1、DP、はsizeof(DP));  
            memcpyの(F2、DP、はsizeof(DP));   
        }        
        ため(J = 255; J> = 0; - J)
        { 
            (; K> = 0; int型のk = 255 - k)に対する
            {                   
                IF((J&[I] .sta)== 0)F1 [ J] [K | [I] .sta] =(F1 [J] [K | [I] .sta] + F1 [J] [K])%のMOD。     
                ((K&[I] .sta)== 0)であれば、F2 [J | [I] .sta] [K] =(F2 [J | [I] .sta] [K] + F2 [J] [ K])%のMOD。      
            } 
        }                 
        (!私== N || [I] .BI || A [i]の.BI = [I + 1] .BI)なら
        、{ 
            (j = 0; J <= 255; ++ J)
            { 
                ための(int型のk = 0; K <= 255; ++ K)          
                {                       
                    DP [J] [K] =(F1 [J] [K] + F2 [J] -dp [J] [K] + MOD [K])%MODを、
                } 
            } 
        }                      
    }        
    LL ANS = 0LL。                         
    ための式(I 0 =; I <= 255; ++ i)がため(J = 0であり、j <= 255; ++ j)の場合((I&J)== 0)(ANS + = DP [I] [J]) %= MOD。    
    printf( "%のLLD \ n"は、ANS)。   
    0を返します。
}

  

おすすめ

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