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 ] = { 1、2、3、5、7、11、13、17、19 }。
構造体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;
}