P2150 [NOI2015]寿司の夕食

https://www.luogu.com.cn/problem/P2150

問題の解決策

nは互いに素でなければならない2つのヘッド群に割り当てられた(1を除く)番号の前に。

プレスF [I] [J]とすることができるだけ30%プライム形状10を考慮すると、素数I、第2グループのJの最初のグループは方法の良い番号を持っている状態を示しています。

显然F [i]は[J&S] + = F [i]は[J](!(I&S))

F [I&S] [J] + = F [i]は[J](!(J&S))

F [0] [0] = 1;

100%を考えてみましょう

予選の年の同じ数の2を持つことができない22以上のみ8つのプライム、および素数で2222内のオープン500を発見しました。私たちは覚えている小さな素数状態s、大きな素数ダの各番号。

大きな素数のすべて同じ、右列は一緒にこのような大きな素数が単一の候補であることを保証します。

3つの配列と転送

コードは以下の通りであります:

#include <ビット/ STDC ++ H>
 に#define INT長い長い
 使用して 名前空間STDを、
const  int型 N = 505 ;
INT、N、MO、ZHI F1 [N] [N]、F2 [N] [N]、DP [N] [N]、[ 10 ] = { 1235711131719 }。
構造体PIGU 
{ 
    int型DA、S。
} [N]。
インラインINTは()読み取り
{ 
    チャー C = GETCHAR()。
    int型のx =0、F = 1 一方、 {(isdigit(C)!)であれば(C == ' - ')、F = - 1 ; C = GETCHAR();}
     ながら(isdigit(c)参照){X =(x << 3)+(X < < 1)+ C- ' 0 ' ; C = GETCHAR();}
     戻り X * F。
} 
インラインint型の追加(int型のx、int型Y)
{ 
    リターン?X + Y> MO X + Y-MO:X + Y。
} 
インラインBOOL CMP(PIGU X、PIGUのY)
{ 
    リターンx.da < y.da。
} 
)(主符号付き
{ 
    N)=(読み取り、MO = (読み取り)
    なら(MO == 1 
    { 
        COUT << " 0 " リターン 0 ; 
    } 
    ためINT iは= 2、I <= N; I ++ 
    { 
        int型 HU = I。
        INT J = 1 ; J <= 8 ; J ++ 
        { 
            一方(HU%ZHI [j] == 0 
            { 
                HU / = ZHI [J]。
                [I] .S | =(1 << J- 1 )。
            } 
        }     
        もし(HU =!1)[I] .da = HU。
    } 
    DP [ 0 ] [ 0 ] = 1 ; 
    ソート( + 2、+ N + 1 、CMP)。
    以下のためにINT iが= 2 ; I <= N; I ++ 
    { 
        場合(![I] .da = [I- 1 ] .da || A [i]が.da == 0 
        {
            ためINT J = 0 ; J <= 255 ; J ++ のためのINT K = 0 ; K <= 255 ; K ++ 
                    F1 [J] [K] = F2 [J] [K] = DP [J] [K]。
        } 
        のためのINT J = 255 ; J> = 0 ; j-- のためのINT K = 255 ; K> = 0 ; k-- であれば(!(J&K))
                { 
                    もし!((J&[I] .S))F2 [J] [K | [I] .S] =(F2 [J] [Kを追加|[I] .S]、F2 [J] [K])。
                    もし(!(K&[I] .S))F1 [J | [I] .S] [K] =アドオン(F1 [J | [I] .S] [k]は、F1 [J] [K ]); 
                } 
        もし([I] .da = [I +!1 ] .da || A [i]が.da == 0 || I == N)
        { 
            ためINT J = 0 ; J <= 255 ; J ++ のためのint型のk = 0 ; K <= 255 ; K ++ 場合!((J&K))
                    { 
                        DP [J] [K] =追加(MO-  DP [j] [k]を、(F1 [j]を追加[K]、F2 [J] [K]))。
                    }
        } 
    } 
    int型 ANS = 0 以下のためにint型私は= 0 ; I <= 255 ; I ++)のためのint型 J = 0 ; J <= 255 ; J ++)の場合 ANS =((I&J)!)を追加(ANS、DP [I] [J]); 
    coutの << ANS; 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/betablewaloot/p/12339756.html