UOJ 129/BZOJ 4197 寿司晚宴 状压DP

 

//By SiriusRen
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=555;
struct Node{int a,p;}node[N];
bool operator<(Node a,Node b){return a.p<b.p;}
char pr[]={2,3,5,7,11,13,17,19};
int n,p,f[N][N],dp[N][N][2],ans;
void div(int x){
    int cpy=x;
    for(int i=0;i<8;i++)
        if(!(x%pr[i])){
            while(x%pr[i]==0)x/=pr[i];
            node[cpy].a|=1<<i;
        }
    node[cpy].p=x;
}
int main(){
    scanf("%d%d",&n,&p);
    for(int i=2;i<=n;i++)div(i);
    sort(node+2,node+1+n),f[0][0]=1;
    for(int i=2;i<=n;i++){
        if(node[i].p==1||node[i].p!=node[i-1].p)
            for(int j=0;j<256;j++)
                for(int k=0;k<256;k++)
                    dp[j][k][0]=dp[j][k][1]=f[j][k];
        for(int j=255;~j;j--)
            for(int k=255;~k;k--){
                if(!(node[i].a&k))(dp[j|node[i].a][k][0]+=dp[j][k][0])%=p;
                if(!(node[i].a&j))(dp[j][k|node[i].a][1]+=dp[j][k][1])%=p;
            }
        if(node[i].p==1||node[i].p!=node[i+1].p)
            for(int j=255;~j;j--)
                for(int k=255;~k;k--)
                    f[j][k]=((dp[j][k][0]+dp[j][k][1]-f[j][k])%p+p)%p;
    }
    for(int i=0;i<256;i++)for(int j=0;j<256;j++)if(!(i&j))(ans+=f[i][j])%=p;
    printf("%d\n",ans);
}

 

posted @ 2017-04-01 08:52  SiriusRen  阅读(139)  评论(0编辑  收藏  举报